spring aop 环绕通知around和其他通知的区别

如题所述

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

package cn.seu.bingluo.ioc;

import java.lang.reflect.InvocationHandler;

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

// 被代理的对象
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 aspects = new ArrayList();
Set<Entry> entrySet = aspectInfos.entrySet();
Object result = null;

//遍历切面列表,找到对应的切面
for (Entry 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;
}
}

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;
}
}

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

package cn.seu.bingluo.ioc;

import java.lang.reflect.InvocationHandler;

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

// 被代理的对象
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 aspects = new ArrayList();
Set<Entry> entrySet = aspectInfos.entrySet();
Object result = null;

//遍历切面列表,找到对应的切面
for (Entry 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;
}

}
温馨提示:答案为网友推荐,仅供参考
相似回答