问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

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

}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...二极管 电动车的电瓶因为出于成本考虑,将新旧电瓶混用,因为旧电池内 ... 两个不同容量的蓄电池并联后怎么防止大容量电池向小容量电池放电 工伤后小孩有抚养费吗,会给多少钱 南京工伤死亡子女抚养费标准 邵阳车管所疫情上班吗 2023年验车推迟吗,2023年检车线什么时候上班 全面复工包括黔江车管所不 江宁车管所什么时候复工 疫情期间交警几点下班? 3d和值多少算中奖? 薏大利总面积,总人口多少? 慢性咽炎怎么办啊 慢性咽炎怎么办都几年了? 慢性咽炎怎么办? 患了慢性咽炎怎么办?怎么办? 意大利人口多少,国土面多少? 意大利面积和人口相当于中国哪个省 有氧运动与无氧运动各有哪些特点? 甲状腺机能亢进的营养代谢有什么特点? 基础代谢降低有什么征兆和表现? 怎么样才能增高?吃胖? 喝水都胖的人,通常都有哪些症状呢?如何改善呢? 大油皮敏感肌有闭口粉刺用哪款护肤品好 肌肉活动时,能量代谢有哪些种类各有什么特征 33岁女性基础代谢率多高算易瘦体质 人体在四季中基础代谢变化的特点 甲状腺功能亢进的高代谢症状是什么 为什么有些人吃的少也胖 有些人吃得多也不胖啊 为什么有些人一吃就胖,而有些人怎么吃也不发胖?什么原因呢?是胖的人吸收太好?还是…? 提高基础代谢真的不会胖了吗 excel合并后居中后还能自动换行吗 tomcat 日志文件里的stdoute.log文件可以删除吗 EXCEL中,如何在合并的单元格中,自动换行与动手换行结合使用 猕猴桃可以做果酱吗 linux怎样消除tomcat日志文件catalinua.out 作业帮App中难道只能拍照搜索或读题搜索,不能直接输入吗? 作业帮搜题不能打字非得拍照么 无语 我是苹果手机 别人给我打电话为什么另一个手机也能显示我的通话记录_百度问一问 作业帮可以输入文字提问吗 如何把流量变流畅苹果8? 一个手机号能登录几个了 一个手机可以登入几个微信 魔兽世界RL宏的命令都有什么呀 一个手机可以登几个?怎么多开?说详细点。 一个手机手机号可以登几个微信 一个手机能上几个 oppo可以登陆几个微信 什么是键盘盘芯? 大家好,请问一个手机最多可以同时登录几个? 电机导线盘圈装进配电箱有什么影响吗?