切面

AnnotationAwareAspectJAutoProxyCreator

  • 将高级 @Aspect 切面统一为低级 Advisor 切面
  • 在合适的时机创建代理
 

findEligibleAdvisors

第一个重要方法 findEligibleAdvisors 找到有【资格】的 Advisors
  1. 有【资格】的 Advisor 一部分是低级的, 可以由自己编写, 如下例中的 advisor3
  1. 有【资格】的 Advisor 另一部分是高级的, 由AnnotationAwareAspectJAutoProxyCreator解析 @Aspect 后获得
public static void main(String[] args) { GenericApplicationContext context = new GenericApplicationContext(); context.registerBean("aspect1", Aspect1.class); context.registerBean("config", Config.class); context.registerBean(ConfigurationClassPostProcessor.class); context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class); // BeanPostProcessor // 创建 -> (*) 依赖注入 -> 初始化 (*) context.refresh(); // for (String name : context.getBeanDefinitionNames()) { // System.out.println(name); // } /* */ AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class); List<Advisor> advisors = creator.findEligibleAdvisors(Target1.class, "target1"); for (Advisor advisor : advisors) { System.out.println(advisor); } /* 第二个重要方法 wrapIfNecessary a. 它内部调用 findEligibleAdvisors, 只要返回集合不空, 则表示需要创建代理 */ // Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1"); // System.out.println(o1.getClass()); // Object o2 = creator.wrapIfNecessary(new Target2(), "target2", "target2"); // System.out.println(o2.getClass()); // // ((Target1) o1).foo(); /* 学到了什么 a. 自动代理后处理器 AnnotationAwareAspectJAutoProxyCreator 会帮我们创建代理 b. 通常代理创建的活在原始对象初始化后执行, 但碰到循环依赖会提前至依赖注入之前执行 c. 高级的 @Aspect 切面会转换为低级的 Advisor 切面, 理解原理, 大道至简 */ } static class Target1 { public void foo() { System.out.println("target1 foo"); } } static class Target2 { public void bar() { System.out.println("target2 bar"); } } @Aspect // 高级切面类 @Order(1) static class Aspect1 { @Before("execution(* foo())") public void before1() { System.out.println("aspect1 before1..."); } @Before("execution(* foo())") public void before2() { System.out.println("aspect1 before2..."); } } @Configuration static class Config { @Bean // 低级切面 public Advisor advisor3(MethodInterceptor advice3) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice3); return advisor; } @Bean public MethodInterceptor advice3() { return invocation -> { System.out.println("advice3 before..."); Object result = invocation.proceed(); System.out.println("advice3 after..."); return result; }; } } }
[TRACE] 16:23:04.827 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.springframework.aop.Advisor] [TRACE] 16:23:04.889 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.aopalliance.intercept.MethodInterceptor] org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR InstantiationModelAwarePointcutAdvisor: expression [execution(* foo())]; advice method [public void org.springframework.aop.framework.autoproxy.A17$Aspect1.before1()]; perClauseKind=SINGLETON InstantiationModelAwarePointcutAdvisor: expression [execution(* foo())]; advice method [public void org.springframework.aop.framework.autoproxy.A17$Aspect1.before2()]; perClauseKind=SINGLETON org.springframework.aop.support.DefaultPointcutAdvisor: pointcut [AspectJExpressionPointcut: () execution(* foo())]; advice [org.springframework.aop.framework.autoproxy.A17$Config$$Lambda$117/0x0000000800d64fc0@558bdf1f]
 
spring给所有代理都加的切面 对应org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR
Config类配置的低级切面 org.springframework.aop.support.DefaultPointcutAdvisor
@Aspect 高级切面会将两个前置通知转化成两个Advisor
  1. InstantiationModelAwarePointcutAdvisor: expression [execution(* foo())]; advice method [public void org.springframework.aop.framework.autoproxy.A17$Aspect1.before1()]; perClauseKind=SINGLETON
  1. InstantiationModelAwarePointcutAdvisor: expression [execution(* foo())]; advice method [public void org.springframework.aop.framework.autoproxy.A17$Aspect1.before2()]; perClauseKind=SINGLETON
 

wrapIfNecessary

  • 它内部调用 findEligibleAdvisors, 只要返回集合不空, 则表示需要创建代理
  • 它的调用时机通常在原始对象初始化后执行, 但碰到循环依赖会提前至依赖注入之前执行
pu blic class A17 { public static void main(String[] args) { GenericApplicationContext context = new GenericApplicationContext(); context.registerBean("aspect1", Aspect1.class); context.registerBean("config", Config.class); context.registerBean(ConfigurationClassPostProcessor.class); context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class); // BeanPostProcessor context.refresh(); AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class); List<Advisor> advisors = creator.findEligibleAdvisors(Target1.class, "target1"); Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1"); System.out.println(o1.getClass()); Object o2 = creator.wrapIfNecessary(new Target2(), "target2", "target2"); System.out.println(o2.getClass()); ((Target1) o1).foo(); } static class Target1 { public void foo() { System.out.println("target1 foo"); } } static class Target2 { public void bar() { System.out.println("target2 bar"); } } @Aspect // 高级切面类 @Order(1) static class Aspect1 { @Before("execution(* foo())") public void before1() { System.out.println("aspect1 before1..."); } @Before("execution(* foo())") public void before2() { System.out.println("aspect1 before2..."); } } @Configuration static class Config { @Bean // 低级切面 public Advisor advisor3(MethodInterceptor advice3) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice3); return advisor; } @Bean public MethodInterceptor advice3() { return invocation -> { System.out.println("advice3 before..."); Object result = invocation.proceed(); System.out.println("advice3 after..."); return result; }; } } }
[TRACE] 16:29:39.903 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.springframework.aop.Advisor] [TRACE] 16:29:39.973 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.aopalliance.intercept.MethodInterceptor] [TRACE] 16:29:40.012 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Creating implicit proxy for bean 'target1' with 0 common interceptors and 4 specific interceptors class org.springframework.aop.framework.autoproxy.A17$Target1$$EnhancerBySpringCGLIB$$4f6cda81 class org.springframework.aop.framework.autoproxy.A17$Target2 aspect1 before1... aspect1 before2... advice3 before... target1 foo advice3 after...

代理的创建时机

  1. 初始化之后 (无循环依赖时)
  1. 实例创建后, 依赖注入前 (有循环依赖时), 并暂存于二级缓存

无循环依赖,初始化之后

 
public class A17_1 { public static void main(String[] args) { GenericApplicationContext context = new GenericApplicationContext(); context.registerBean(ConfigurationClassPostProcessor.class); context.registerBean(Config.class); context.refresh(); context.close(); // 创建 -> (*) 依赖注入 -> 初始化 (*) /* 学到了什么 a. 代理的创建时机 1. 初始化之后 (无循环依赖时) 2. 实例创建后, 依赖注入前 (有循环依赖时), 并暂存于二级缓存 b. 依赖注入与初始化不应该被增强, 仍应被施加于原始对象 */ } @Configuration static class Config { @Bean // 解析 @Aspect、产生代理 public AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator() { return new AnnotationAwareAspectJAutoProxyCreator(); } @Bean // 解析 @Autowired public AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor() { return new AutowiredAnnotationBeanPostProcessor(); } @Bean // 解析 @PostConstruct public CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor() { return new CommonAnnotationBeanPostProcessor(); } @Bean public Advisor advisor(MethodInterceptor advice) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); return new DefaultPointcutAdvisor(pointcut, advice); } @Bean public MethodInterceptor advice() { return (MethodInvocation invocation) -> { System.out.println("before..."); return invocation.proceed(); }; } @Bean public Bean1 bean1() { return new Bean1(); } @Bean public Bean2 bean2() { return new Bean2(); } } static class Bean1 { public void foo() { } public Bean1() { System.out.println("Bean1()"); } // @Autowired public void setBean2(Bean2 bean2) { // System.out.println("Bean1 setBean2(bean2) class is: " + bean2.getClass()); // } @PostConstruct public void init() { System.out.println("Bean1 init()"); } } static class Bean2 { public Bean2() { System.out.println("Bean2()"); } @Autowired public void setBean1(Bean1 bean1) { System.out.println("Bean2 setBean1(bean1) class is: " + bean1.getClass()); } @PostConstruct public void init() { System.out.println("Bean2 init()"); } }
[INFO ] 17:20:27.651 [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.aop.framework.autoproxy.A17_1$Config' of type [org.springframework.aop.framework.autoproxy.A17_1$Config$$EnhancerBySpringCGLIB$$4ebf3912] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) [TRACE] 17:20:27.682 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.springframework.aop.Advisor] [TRACE] 17:20:27.683 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.aopalliance.intercept.MethodInterceptor] Bean1() Bean1 init() [TRACE] 17:20:27.733 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Creating implicit proxy for bean 'bean1' with 0 common interceptors and 2 specific interceptors Bean2() Bean2 setBean1(bean1) class is: class org.springframework.aop.framework.autoproxy.A17_1$Bean1$$EnhancerBySpringCGLIB$$2d106fac Bean2 init()@Autowired public void setBean1(Bean1 bean1) { System.out.println("Bean2 setBean1(bean1) class is: " + bean1.getClass()); }

有循环依赖 实例创建后, 依赖注入前

static class Bean1 { public void foo() { } public Bean1() { System.out.println("Bean1()"); } @Autowired public void setBean2(Bean2 bean2) { System.out.println("Bean1 setBean2(bean2) class is: " + bean2.getClass()); } @PostConstruct public void init() { System.out.println("Bean1 init()"); } } static class Bean2 { public Bean2() { System.out.println("Bean2()"); } @Autowired public void setBean1(Bean1 bean1) { System.out.println("Bean2 setBean1(bean1) class is: " + bean1.getClass()); } @PostConstruct public void init() { System.out.println("Bean2 init()"); } }
[INFO ] 17:22:34.178 [main] o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.aop.framework.autoproxy.A17_1$Config' of type [org.springframework.aop.framework.autoproxy.A17_1$Config$$EnhancerBySpringCGLIB$$4ebf3912] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) [TRACE] 17:22:34.208 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.springframework.aop.Advisor] [TRACE] 17:22:34.210 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.aopalliance.intercept.MethodInterceptor] Bean1() Bean2() [TRACE] 17:22:34.305 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Creating implicit proxy for bean 'bean1' with 0 common interceptors and 2 specific interceptors Bean2 setBean1(bean1) class is: class org.springframework.aop.framework.autoproxy.A17_1$Bean1$$EnhancerBySpringCGLIB$$2741d750 Bean2 init() Bean1 setBean2(bean2) class is: class org.springframework.aop.framework.autoproxy.A17_1$Bean2 Bean1 init()

切面顺序@Order

public class A17 { public static void main(String[] args) { GenericApplicationContext context = new GenericApplicationContext(); context.registerBean("aspect1", Aspect1.class); context.registerBean("config", Config.class); context.registerBean(ConfigurationClassPostProcessor.class); context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class); context.refresh(); AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class); List<Advisor> advisors = creator.findEligibleAdvisors(Target1.class, "target1"); Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1"); System.out.println(o1.getClass()); Object o2 = creator.wrapIfNecessary(new Target2(), "target2", "target2"); System.out.println(o2.getClass()); ((Target1) o1).foo(); } static class Target1 { public void foo() { System.out.println("target1 foo"); } } static class Target2 { public void bar() { System.out.println("target2 bar"); } } @Aspect // 高级切面类 @Order(1) static class Aspect1 { @Before("execution(* foo())") public void before1() { System.out.println("aspect1 before1..."); } @Before("execution(* foo())") public void before2() { System.out.println("aspect1 before2..."); } } @Configuration static class Config { @Bean // 低级切面 public Advisor advisor3(MethodInterceptor advice3) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice3); return advisor; } @Bean public MethodInterceptor advice3() { return invocation -> { System.out.println("advice3 before..."); Object result = invocation.proceed(); System.out.println("advice3 after..."); return result; }; } } }
Aspect1 切面优先级更高
aspect1 before1... aspect1 before2... advice3 before... target1 foo advice3 after...
设置 Aspect1 的@Order(2) config 设置 advisor.setOrder(1);
@Aspect // 高级切面类 @Order(2) static class Aspect1 { @Before("execution(* foo())") public void before1() { System.out.println("aspect1 before1..."); } @Before("execution(* foo())") public void before2() { System.out.println("aspect1 before2..."); } } @Configuration static class Config { @Bean // 低级切面 public Advisor advisor3(MethodInterceptor advice3) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(* foo())"); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice3); advisor.setOrder(1); return advisor; } @Bean public MethodInterceptor advice3() { return invocation -> { System.out.println("advice3 before..."); Object result = invocation.proceed(); System.out.println("advice3 after..."); return result; }; } }
advice3 before... aspect1 before1... aspect1 before2... target1 foo advice3 after...