AOP中的around的执行过程是怎样的
发布网友
发布时间:2022-04-12 19:34
我来回答
共1个回答
热心网友
时间:2022-04-12 21:04
之前自己用JDK动态代理实现过AOP功能,做得比较粗糙,仅供参考。
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;
}
}
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<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;
}
}