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包下的拦截体系

架构分析

在这里插入图片描述

其中DefaultAdvisorAutoProxyCreator这个类功能更为强大,这个类的奇妙之处是他实现BeanPostProcessor接口,当ApplicationContext读取所有的Bean配置信息后,这个类将扫描上下文,寻找所有的Advisor对象(一个Advisor由切入点和通知组成),将这些Advisor应用到所有符合切入点的Bean中。

实际案例

项目结构

在这里插入图片描述

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名字为方法名

  1. DefaultAdvisorAutoProxyCreator对象会在容器启动时扫描Advisor对象
  2. 然后基于切入点为目标对象创建代理对象
  3. 然后再执行切入点方法时,自动执行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");	}}

在这里插入图片描述

上一篇:Shiro安全框架
下一篇:java--邮件与短信

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2025年04月12日 18时43分48秒