AOP中的around的执行过程是怎样的啊?

欣儿 发布于 2013/11/12 17:52
阅读 1K+
收藏 0

AOP中的around的执行过程是怎样的啊?

PS:有代码说明就更好啦

加载中
0
你是错的我恒对
你是错的我恒对

个人理解,极有可能是错的

spring容器启动时,解析注解,根据各个方法上的注解,生成相对于注解该类的代理类(after before等),然后  代码注入的都是 这个代理类(代理类已经加上 各种 需要织入的逻辑了)

动态代理实现有点绕的,我已经忘了代码那种生成方式了,字节码方式不懂

0
CoserSeu
CoserSeu
spring中有jdk动态代理和CGLIB两种实现。
0
CoserSeu
CoserSeu

之前自己用JDK动态代理实现过AOP功能,做得比较粗糙,仅供参考。

ProxyHandler.java

package cn.seu.bingluo.ioc;

import java.lang.reflect.InvocationHandler;

/*
 * 代理类
 * 运用jdk动态代理实现,要求前提是被代理对象实现接口
 */
public class ProxyHandler implements InvocationHandler {
	// 存储所有切面
	private static HashMap<String, AspectInfo> aspectInfos = new HashMap<String, AspectInfo>();

	// 被代理的对象
	private Object target = null;

	public ProxyHandler(Object target) {
		this.target = target;
	}

	public static void addAspectInfo(AspectInfo aspectInfo) {
		aspectInfos.put(aspectInfo.getExpression(), aspectInfo);
	}

	// 获取代理实例
	public Object getProxyInstance() {
		if (target == null) {
			return null;
		}
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(), this);
	}

	// 获取代理实例
	public Object getProxyInstance(Object target) {
		if (target == null) {
			return null;
		}
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(),
				target.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		ArrayList<AspectInfo> aspects = new ArrayList<AspectInfo>();
		Set<Entry<String, AspectInfo>> entrySet = aspectInfos.entrySet();
		Object result = null;

		//遍历切面列表,找到对应的切面
		for (Entry<String, AspectInfo> entry : entrySet) {
			AspectInfo aspectInfo = entry.getValue();
			Object adviceBean = aspectInfo.getAdviceBean();
			String expression = aspectInfo.getExpression();

			Pattern pattern = Pattern.compile(expression);
			Matcher matcher = pattern.matcher(target.getClass().getName() + "."
					+ method.getName());
			if (matcher.find()) {
				AspectInfo aspect = new AspectInfo();
				aspect.setAdviceBean(adviceBean);
				aspect.setBeforeMethod(aspectInfo.getBeforeMethod());
				aspect.setAroundMethod(aspectInfo.getAroundMethod());
				aspect.setAfterMethod(aspectInfo.getAfterMethod());
				aspects.add(aspect);
			}
		}

		// 执行before增强
		for (AspectInfo aspect : aspects) {
			Object adviceBean = aspect.getAdviceBean();
			if (aspect.getBeforeMethod() != null) {
				aspect.getBeforeMethod().invoke(adviceBean, new Object[]{});
			}
		}

		// 执行around增强
		Object aroundAdviceBean = target;
		Method aroundAdviceMethod = method;
		Object[] aroundAdviceArgs = args;
		for (AspectInfo aspect : aspects) {
			Object adviceBean = aspect.getAdviceBean();
			if (aspect.getAroundMethod() != null) {
				aroundAdviceArgs = new Object[] { new ProceedingJoinPoint(
						aroundAdviceBean, aroundAdviceMethod, aroundAdviceArgs) };
				aroundAdviceBean = adviceBean;
				aroundAdviceMethod = aspect.getAroundMethod();
			}
		}
		result = aroundAdviceMethod.invoke(aroundAdviceBean, aroundAdviceArgs);

		// 执行After增强
		for (AspectInfo aspect : aspects) {
			Object adviceBean = aspect.getAdviceBean();
			if (aspect.getAfterMethod() != null) {
				aspect.getAfterMethod().invoke(adviceBean, new Object[]{});
			}
		}
		return result;
	}

}

ProceedingJoinPoint.java
package cn.seu.bingluo.ioc;

import java.lang.reflect.InvocationTargetException;

/*
 * 用于处理AOP代理链时,封装相关信息作为统一参数进行传递
 */
public class ProceedingJoinPoint {
	private Object object;//被代理的对象
	private Method method;//被代理的方法
	private Object[] args;//方法相应的参数

	public ProceedingJoinPoint(Object object, Method method, Object[] args){
		this.object = object;
		this.method = method;
		this.args = args;
	}

	//执行目标函数
	public Object excute(){
		Object result = null;
		try {
			result = method.invoke(object, args);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return result;
	}
}

AspectInfo.java

package cn.seu.bingluo.ioc;

import java.lang.reflect.Method;

/*
 * 切面信息Bean
 * 每1个切面最多只有:
 * 1个切点expression
 * 1个增强bean
 * 1个前置增强、环绕增强、后置增强
 */
public class AspectInfo {
	private String expression = "";
	private Object adviceBean = null;
	private Method beforeMethod = null;
	private Method aroundMethod = null;
	private Method afterMethod = null;

	public AspectInfo(){

	}

	public AspectInfo(String expression, Object adviceBean,
			Method beforeMethod, Method aroundMethod, Method afterMethod) {
		setExpression(expression);
		setAdviceBean(adviceBean);
		setBeforeMethod(beforeMethod);
		setAroundMethod(aroundMethod);
		setAfterMethod(afterMethod);
	}

	public String getExpression() {
		return expression;
	}

	public void setExpression(String expression) {
		this.expression = expression;
	}

	public Object getAdviceBean() {
		return adviceBean;
	}

	public void setAdviceBean(Object adviceBean) {
		this.adviceBean = adviceBean;
	}

	public Method getBeforeMethod() {
		return beforeMethod;
	}

	public void setBeforeMethod(Method beforeMethod) {
		this.beforeMethod = beforeMethod;
	}

	public Method getAroundMethod() {
		return aroundMethod;
	}

	public void setAroundMethod(Method aroundMethod) {
		this.aroundMethod = aroundMethod;
	}

	public Method getAfterMethod() {
		return afterMethod;
	}

	public void setAfterMethod(Method afterMethod) {
		this.afterMethod = afterMethod;
	}
}
(高亮失败,重发一遍 = =)
 

0
逝水流炎
逝水流炎
简直桑心病狂。
返回顶部
顶部