(一)注解方式注册流程原理


是在配置类上配置@EnableAspectJAutoProxy的
需要注意的是@EnableAspectJAutoProxy 需要被@ComponentScan扫描到才行,不然没有作用.
被@ComponentScan扫描到之后,会加载这个注解里面的@Import注解标注的AspectJAutoProxyRegistrar类(ImportBeanDefinitionRegistrar的实现类)




AspectJAutoProxyRegistrar被导入进来了,Spring在容器启动的时候ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars会调用到registerBeanDefinitions,
就会执行AspectJAutoProxyRegistrar#registerBeanDefinitions 内部逻辑是
—————————-

调用
AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)调用
AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)调用
AopConfigUtils#registerOrEscalateApcAsRequired给
AnnotationAwareAspectJAutoProxyCreator 变成BeanDefinition对象,放入BeanDefinitionRegistry里面

—————————————
然后AspectJAutoProxyRegistrar#registerBeanDefinitions方法接着执行解析
@EnableAspectJAutoProxy上面的配置属性,比如说指定JDK还是CGLib动态代理等等配置属性,解析完了保存到BeanDefinitionRegistry里面的BeanDefinition

最后通过BeanDefinitionRegistry给BeanDefinition对象注册到Spring容器里面.

AspectJAutoProxyRegistrar

  1. class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
  2. /**
  3. * Register, escalate, and configure the AspectJ auto proxy creator based on the value
  4. * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
  5. * {@code @Configuration} class.
  6. */
  7. @Override
  8. public void registerBeanDefinitions(
  9. AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
  10. AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
  11. //注册一个AOP代理实现的Bean
  12. AnnotationAttributes enableAspectJAutoProxy =
  13. AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
  14. if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
  15. AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
  16. }
  17. if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
  18. AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
  19. }
  20. }
  21. }



spectJAutoProxyRegistrar 根据注解@EnableAspectJAutoProxy上的属性来注册相应的Bean,proxyTargetClass = true 指定使用CGLIB来作为AOP的代理实现方式。若不设置此属性,则默认使用jdk proxy作为代理实现方式。他们两者的区别是: jdk动态代理只支持接口的方法代理,不支持类自身的方法,它动态地生成一个代理类,继承自Proxy,实现被代理的接口,内部持有被代理对象;而CGLIB则支持所有的方法代理,它动态生成一个代理类,继承自被代理类,所以叫TargetClass。

AopConfigUtils

  1. public abstract class AopConfigUtils {
  2. //有三种AOP的配置形式,有基于Spring内置的,有基于用户配置文件的,有基于注解的,基于注解的优先级最高,
  3. //一般配置一种就可以,如果配置多种则优先级高的会覆盖优先级低的
  4. static {
  5. APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
  6. APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
  7. APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
  8. }
  9. public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
  10. return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
  11. }
  12. //注册AnnotationAwareAspectJAutoProxyCreator到容器中,此类负责基于注解的AOP动态代理实现
  13. public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
  14. return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
  15. }
  16. //设置支持类的代理,设置此属性到时候会使用CGLIB来生成动态代理类
  17. public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
  18. if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
  19. BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
  20. definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
  21. }
  22. }
  23. private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
  24. Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
  25. if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
  26. BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
  27. if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
  28. int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
  29. int requiredPriority = findPriorityForClass(cls);
  30. //通过比较代理类在集合中的序号来确定优先级,基于注解形式的优先级高
  31. if (currentPriority < requiredPriority) {
  32. apcDefinition.setBeanClassName(cls.getName());
  33. }
  34. }
  35. return null;
  36. }
  37. RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
  38. beanDefinition.setSource(source);
  39. beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
  40. beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  41. registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
  42. return beanDefinition;
  43. }
  44. }





2.AspectJAutoProxyRegistrar被扫描过程(@ComponentScan工作过程)


ConfigurationClassParser#parse(AnnotationMetadata, java.lang.String)调用ConfigurationClassParser#processConfigurationClass调用
ConfigurationClassParser#doProcessConfigurationClass
里面通过@ComponentScans扫描到的 ,然后调用
ComponentScanAnnotationParser#parse调用
ClassPathBeanDefinitionScanner#doScan 把扫描到的所有的Bean 变成BeanDefinition对象
在ClassPathBeanDefinitionScanner#doScan 方法里面除了给所有的Bean变成
BeanDefinition之外,还会检查BeanDefinition是否有@Import或者@ComponentScan或者@ImportResources 等等,它又要去递归检测是否符合条件的 Bean变成BeanDefinition对象.




(二)XML方式设置方式(不要研究了)



AspectJAwareAdvisorAutoProxyCreator 是xml方式的入口类.xml配置的 不过这个要被淘汰了.因为现在xml已经被整体淘汰了.





基于xml配置解析的方式,扫描Spring.xml 的 标签,完成这个标签的入口类的注册,这个标签的解析是找AOPjar包的spring.handlers 的SPI配置文件,然后找到解析类
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
点击去看到这个类里面有个init方法,找到下面代码块儿:
registerBeanDefinitionParser(“aspectj-autoproxy”, new AspectJAutoProxyBeanDefinitionParser());

就能看到解析标签的解析类是下面的解析类了
org.springframework.aop.config.AspectJAutoProxyBeanDefinitionParser

找到AspectJAutoProxyBeanDefinitionParser 类的
AspectJAutoProxyBeanDefinitionParser#parse调用
AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary,这个方法就是xml的AOP入口类的注册的地方了
内部逻辑是:
———————————————————

registerAspectJAnnotationAutoProxyCreatorIfNecessary调用了
AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object) 调用了
AopConfigUtils#registerOrEscalateApcAsRequired方法注册了
AnnotationAwareAspectJAutoProxyCreator,把AnnotationAwareAspectJAutoProxyCreator这个类变成了BeanDefinition对象
———————————————————-