
Spring--05--AOP原生实现方式
发布日期:2021-05-04 19:53:58
浏览次数:22
分类:精选文章
本文共 3092 字,大约阅读时间需要 10 分钟。
概述
Spring 整合AspectJ框架实现AOP只是Spring框架中AOP的一种实现方式,此方式相对比较简单,实现方便。但此方式底层还是要转换为Spring原生AOP的实现,Spring AOP原生方式实现的核心有三大部分构成,分别是:
- JDK代理。
- CGLIB代理
- org.aopalliance包下的拦截体系
架构分析
实际案例
项目结构
PjApplication主启动类
主启动类 配置 DefaultAdvisorAutoProxyCreator对象 ,一般是配置在配置类上,这里为了简化代码,放在主启动类上.
@SpringBootApplicationpublic class PjApplication { @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { //此对象会在容器启动时扫描Advisor对象,然后基于切入点为目标对象创建代理对象 //然后再执行切入点方法时,自动执行Advice对象通知方法 return new DefaultAdvisorAutoProxyCreator(); } public static void main(String[] args) { SpringApplication.run(CgbSourceAop01Application.class, args); }}
@Bean注解应用于配置类中(使用了@Configuration修饰)
@Bean描述的方法其返回值会交给spring管理,spring管理这个bean默认bean名字为方法名
- DefaultAdvisorAutoProxyCreator对象会在容器启动时扫描Advisor对象
- 然后基于切入点为目标对象创建代理对象
- 然后再执行切入点方法时,自动执行Advice对象通知方法
RequiredLog 注解
/**借助此注解描述切入点方法*/@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface RequiredLog { }
service 接口
public interface MailService { boolean sendMsg(String msg);}
MailServiceImpl 目标方法实现类
@Servicepublic class MailServiceImpl implements MailService { @RequiredLog //希望这个注解描述的方法为一个切入点方法(目标方法) @Override public boolean sendMsg(String msg) { //System.out.println("start:"+System.currentTimeMillis()); System.out.println("send "+msg); //System.out.println("end:"+System.currentTimeMillis()); return true; }}
LogAdvice 通知方法
继承 MethodInterceptor接口
/** * 日志通知对象 */public class LogAdvice implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("start:"+System.currentTimeMillis()); Object result=invocation.proceed();//执行目标方法 System.out.println("end:"+System.currentTimeMillis()); return result; }}
- 切入点对应的目标方法执行之前执行,可以在目标方法执行之前和之后做点拓展业务
- invocation连接点对象(封装了要执行的目标方法信息,可以通过反射调用目标方法)
LogAdvisor 顾问 (内部注册通知,判断切入点方法)
实现啦 Advisor接口
Spring容器在启动时会基于BeanPostProcessor找到所有的Advisor对象(顾问),并基于Advisor对象中切入点的描述为目标对象创建代理对象.当执行目标方法时会执行Advisor对象关联通知.
@Componentpublic class LogAdvisor extends StaticMethodMatcherPointcutAdvisor { private static final long serialVersionUID = -3987392064269894257L; public LogAdvisor() { //在advisor内部注册一个日志通知 setAdvice(new LogAdvice()); } /** * * matches方法用于判定方法参数中的method是否为一个切入点方法,当它的返回值 * 为true时,表示参数中的method对象为一个切入点方法. * @param method 对应了目标方法对象(可能是目标方法所在类的父类方法对象) * @param targetClass 代表目标对象类型 */ @Override public boolean matches(Method method, Class targetClass) { try { Method targetMethod= targetClass.getMethod(method.getName(), method.getParameterTypes()); //检测目标方法上是否有requiredLog注解 return targetMethod.isAnnotationPresent(RequiredLog.class); }catch(Exception e) { return false; } }}
测试 Tests
@SpringBootTestpublic class MailServiceTests { @Autowired private MailService mailService; @Test void testSendMsg() { mailService.sendMsg("hello cgb2006"); }}
发表评论
最新留言
网站不错 人气很旺了 加油
[***.192.178.218]2025年04月12日 18时43分48秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
给asterisk1.8.7添加menuselct选项
2019-03-06
组合模式
2019-03-06
PyQt5之音乐播放器
2019-03-06
css居中方法与双飞翼布局
2019-03-06
Redis进阶实践之十八 使用管道模式提高Redis查询的速度
2019-03-06
SQL注入
2019-03-06
XCTF-upload1
2019-03-06
LeetCode 题解 | 1. 两数之和
2019-03-06
#2036:改革春风吹满地
2019-03-06
MPI Maelstrom POJ - 1502 ⭐⭐ 【Dijkstra裸题】
2019-03-06
P1379 八数码难题 ( A* 算法 与 IDA_star 算法)
2019-03-06
按需取余
2019-03-06
算法学习笔记: 珂朵莉树
2019-03-06
算法学习笔记:母函数详解
2019-03-06
Codeforces Round #664 题解(A ~ C)
2019-03-06
Problem 1342B - Binary Period (思维)
2019-03-06
Problem A - Sequence with Digits (数学推导)
2019-03-06
Problem 330A - Cakeminator (思维)
2019-03-06