飞道的博客

spring AOP 源码 详解一

377人阅读  评论(0)

目录

 

概念:

AOP

源码

@EnableAspectJAutoProxy

@EnableAspectJAutoProxyz这个是什么?

AspectJAutoProxyRegistrar这个类

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware接口

AnnotationAwareAspectJAutoProxyCreator实现BeanPostProcessor接口

AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口

创建代理对象

流程图


概念:

AOP

AOP(Aspect Oriented Programming),即面向切面编程。简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

源码

@EnableAspectJAutoProxy

@EnableAspectJAutoProxyz这个是什么?

我们可以注意到,当我们要自己写一个切面的时候,在我们的配置类上面都会加上@EnableAspectJAutoProxy这个注解,那么这个注解是什么呢?这个注解的作用是让你自己写的切面起作用,那么他是怎么让我们的切面起作用的呢,下面来看一下这个注解如下图:

从这个注解中我们一眼就看出,他通过@Import注解引入了AspectJAutoProxyRegistrar这个类。

AspectJAutoProxyRegistrar这个类

AspectJAutoProxyRegistrar这个类是干什么的?

当我们进入到AspectJAutoProxyRegistrar这个类的时候,看到了他实现了ImportBeanDefinitionRegistrar这个类,ImportBeanDefinitionRegistrar这个有必要说一下,在我前几篇博客中提到过这个类,只要实现了ImportBeanDefinitionRegistrar,就可以往我们的容器中添加bean定义,那么他在这里的作用是什么呢?来看一下他的源码。

    org.springframework.context.annotation.AspectJAutoProxyRegistrar#registerBeanDefinitions
        org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
            org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)


  
  1. @Nullable
  2. public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
  3. BeanDefinitionRegistry registry, @Nullable Object source) {
  4. //注册一个名称叫org.springframework.aop.config.internalAutoProxyCreator 类型是AnnotationAwareAspectJAutoProxyCreator的bean定义
  5. return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
  6. }

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator这个是类是干什么的呢?我们来看一下他的继承关系图

然后我们根据集成图,来看一下AnnotationAwareAspectJAutoProxyCreator干了些什么:

AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware接口

首先他实现了BeanFactoryAware接口,而我们看一下BeanFactoryAware源码,他到底是干什么的?


  
  1. public interface BeanFactoryAware extends Aware {
  2. void setBeanFactory(BeanFactory beanFactory) throws BeansException;
  3. }

BeanFactoryAware很简单,就一个setBeanFactory方法,AbstractAutoProxyCreator实现了BeanFactoryAware,一定会复写这个方法,然后我们看一下AbstractAutoProxyCreator的setBeanFactory方法:

    org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#setBeanFactory
        org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory


  
  1. @Override
  2. public void setBeanFactory(BeanFactory beanFactory) {
  3. super.setBeanFactory(beanFactory); //调用父类的super.setBeanFactory(beanFactory);
  4. if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
  5. throw new IllegalArgumentException(
  6. "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
  7. }
  8. initBeanFactory((ConfigurableListableBeanFactory) beanFactory); //初始化bean工厂
  9. }

那么这个initBeanFactory()是怎么实现的呢,来看一下他的源码

    org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#initBeanFactory
        org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#initBeanFactory


  
  1. @Override
  2. protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
  3. super.initBeanFactory(beanFactory); //1.调用父类的setBeanFactory
  4. if ( this.aspectJAdvisorFactory == null) { // 若 apsectj的Advisor(通知)工厂对象为空,我们就创建一个ReflectiveAspectJAdvisorFactory
  5. this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
  6. }
  7. //不为空 我们就把aspectJAdvisorFactory 包装为BeanFactoryAspectJAdvisorsBuilderAdapter
  8. this.aspectJAdvisorsBuilder =
  9. new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
  10. }

总结:实现BeanFactoryAware接口主要做了两件事:1.setBeanFactory 2.为aspectJAdvisorsBuilder的Advisor(通知)赋值

AnnotationAwareAspectJAutoProxyCreator实现BeanPostProcessor接口

我们先看看BeanPostProcessor这个接口的源码:


  
  1. public interface BeanPostProcessor {
  2. @Nullable
  3. default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  4. return bean;
  5. }
  6. @Nullable
  7. default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  8. return bean;
  9. }

这个接口有两个方法postProcessBeforeInitialization和postProcessAfterInitialization方法,但是AnnotationAwareAspectJAutoProxyCreator实现BeanPostProcessor接口主要是用它的postProcessAfterInitialization方法,我们来看一下AnnotationAwareAspectJAutoProxyCreator中的postProcessAfterInitialization方法源码


  
  1. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
  2. if (bean != null) {
  3. Object cacheKey = getCacheKey(bean.getClass(), beanName);
  4. if ( this.earlyProxyReferences.remove(cacheKey) != bean) {
  5. return wrapIfNecessary(bean, beanName, cacheKey); //包装bean 创建代理对象
  6. }
  7. }
  8. return bean;
  9. }

AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口

AnnotationAwareAspectJAutoProxyCreator实现InstantiationAwareBeanPostProcessor接口主要是用它的postProcessBeforeInstantiation方法,看一下这个方法的源码:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation


  
  1. @Override //找通知(advisor),放入缓存
  2. public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
  3. Object cacheKey = getCacheKey(beanClass, beanName);
  4. if (!StringUtils.hasLength(beanName) || ! this.targetSourcedBeans.contains(beanName)) { //判断有没有处理过
  5. if ( this.advisedBeans.containsKey(cacheKey)) {
  6. return null;
  7. } //是不是一些基础的bean(Advice,Pointcut,Advisor,AopInfrastructureBean)||该不该跳过
  8. if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { //shouldSkip源码
  9. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  10. return null;
  11. }
  12. }
  13. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); // 获取封装当前bean的TargetSource对象,如果不存在,则直接退出当前方法,
  14. if (targetSource != null) { // 否则从TargetSource中获取当前bean对象,并且判断是否需要将切面逻辑应用在当前bean上。
  15. if (StringUtils.hasLength(beanName)) {
  16. this.targetSourcedBeans.add(beanName);
  17. }
  18. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
  19. Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
  20. this.proxyTypes.put(cacheKey, proxy.getClass());
  21. return proxy;
  22. }
  23. return null;
  24. }

创建代理对象

真正的创建代理对象是从BeanPostProcessor处理器的后置方法开始,看源码路径:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
    org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
        org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
            org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
                org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply
                    org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

然后我们分别来看一下他们的源码;

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization


  
  1. @Override //实例化之后
  2. public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
  3. if (bean != null) {
  4. Object cacheKey = getCacheKey(bean.getClass(), beanName); ////通过传入的class 和beanName生成缓存key
  5. if ( this.earlyProxyReferences.remove(cacheKey) != bean) {
  6. return wrapIfNecessary(bean, beanName, cacheKey); //有没有必要包装
  7. }
  8. }
  9. return bean;
  10. }

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary


  
  1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  2. if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { //有没有被代理过
  3. return bean;
  4. }
  5. if (Boolean.FALSE.equals( this.advisedBeans.get(cacheKey))) { //不需要被通知的直接返回
  6. return bean;
  7. }
  8. if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { //是不是基础bean || 是否需要跳过
  9. this.advisedBeans.put(cacheKey, Boolean.FALSE);
  10. return bean;
  11. }
  12. // Create proxy if we have advice.
  13. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //获取通知 源码
  14. if (specificInterceptors != DO_NOT_PROXY) { //获取的不为空
  15. this.advisedBeans.put(cacheKey, Boolean.TRUE);
  16. Object proxy = createProxy( //创建代理对象 源码
  17. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
  18. this.proxyTypes.put(cacheKey, proxy.getClass());
  19. return proxy;
  20. }
  21. this.advisedBeans.put(cacheKey, Boolean.FALSE); //加入advisedBeans集合中
  22. return bean;
  23. }

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean


  
  1. protected Object[] getAdvicesAndAdvisorsForBean( //找到符合条件的通知
  2. Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
  3. List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); //找到合适的通知
  4. if (advisors.isEmpty()) {
  5. return DO_NOT_PROXY;
  6. }
  7. return advisors.toArray();
  8. }

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors


  
  1. protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  2. List<Advisor> candidateAdvisors = findCandidateAdvisors(); //找候选的通知
  3. List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //找到能用的Advisor
  4. extendAdvisors(eligibleAdvisors);
  5. if (!eligibleAdvisors.isEmpty()) {
  6. eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  7. }
  8. return eligibleAdvisors;
  9. }

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors


  
  1. @Override
  2. protected List<Advisor> findCandidateAdvisors() {
  3. // Add all the Spring advisors found according to superclass rules.
  4. List<Advisor> advisors = super.findCandidateAdvisors(); //找到事务的增强器
  5. // Build Advisors for all AspectJ aspects in the bean factory.
  6. if ( this.aspectJAdvisorsBuilder != null) {
  7. advisors.addAll( this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); //buildAspectJAdvisors 找AspectJ的增强器
  8. }
  9. return advisors;
  10. }
  • 解析findCandidateAdvisors 步骤1.findAdvisorBeans

org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans


  
  1. public List<Advisor> findAdvisorBeans() {
  2. String[] advisorNames = this.cachedAdvisorBeanNames; //去缓存中找通知
  3. if (advisorNames == null) { //没有获取到
  4. // Do not initialize FactoryBeans here: We need to leave all regular beans
  5. // uninitialized to let the auto-proxy creator apply to them!
  6. advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( //从IOC容器中找到所有实现Advisor的实现类的beanName
  7. this.beanFactory, Advisor.class, true, false);
  8. this.cachedAdvisorBeanNames = advisorNames; //赋值给增强器缓存
  9. }
  10. if (advisorNames.length == 0) { //在IOC容器中没有获取到直接返回
  11. return new ArrayList<>();
  12. }
  13. List<Advisor> advisors = new ArrayList<>();
  14. for (String name : advisorNames) { //遍历所有的通知(advisor)
  15. if (isEligibleBean(name)) {
  16. if ( this.beanFactory.isCurrentlyInCreation(name)) { //忽略正在创建的advisor
  17. if (logger.isDebugEnabled()) {
  18. logger.debug( "Skipping currently created advisor '" + name + "'");
  19. }
  20. }
  21. else {
  22. try { //通过getBean的形式创建通知(advisot) //并且将bean 添加到advisors中
  23. advisors.add( this.beanFactory.getBean(name, Advisor.class));
  24. }
  25. catch (BeanCreationException ex) {
  26. Throwable rootCause = ex.getMostSpecificCause();
  27. if (rootCause instanceof BeanCurrentlyInCreationException) {
  28. BeanCreationException bce = (BeanCreationException) rootCause;
  29. String bceBeanName = bce.getBeanName();
  30. if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
  31. if (logger.isDebugEnabled()) {
  32. logger.debug( "Skipping advisor '" + name +
  33. "' with dependency on currently created bean: " + ex.getMessage());
  34. }
  35. continue;
  36. }
  37. }
  38. throw ex;
  39. }
  40. }
  41. }
  42. }
  43. return advisors;
  44. }
  • 解析findCandidateAdvisors 步骤 2.buildAspectJAdvisors

org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors


  
  1. public List<Advisor> buildAspectJAdvisors() {
  2. List<String> aspectNames = this.aspectBeanNames; //从缓存中获取
  3. if (aspectNames == null) { //缓存中没有获取到
  4. synchronized ( this) {
  5. aspectNames = this.aspectBeanNames; //再次冲缓存中获取
  6. if (aspectNames == null) {
  7. List<Advisor> advisors = new ArrayList<>();
  8. aspectNames = new ArrayList<>();
  9. String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( //找到所有的beanName
  10. this.beanFactory, Object.class, true, false);
  11. for (String beanName : beanNames) { //遍历beanNames
  12. if (!isEligibleBean(beanName)) {
  13. continue;
  14. }
  15. Class<?> beanType = this.beanFactory.getType(beanName); //获取bean的类型
  16. if (beanType == null) {
  17. continue;
  18. }
  19. if ( this.advisorFactory.isAspect(beanType)) { //判断是不是切面 源码
  20. aspectNames.add(beanName);
  21. AspectMetadata amd = new AspectMetadata(beanType, beanName); //创建Aspect类的源信息对象
  22. if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
  23. MetadataAwareAspectInstanceFactory factory =
  24. new BeanFactoryAspectInstanceFactory( this.beanFactory, beanName);
  25. List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); //从aspectj中获取通知(advisor) 源码
  26. if ( this.beanFactory.isSingleton(beanName)) {
  27. this.advisorsCache.put(beanName, classAdvisors); //key 类名 value 通知(advisor)
  28. }
  29. else {
  30. this.aspectFactoryCache.put(beanName, factory);
  31. }
  32. advisors.addAll(classAdvisors);
  33. }
  34. else {
  35. // Per target or per this.
  36. if ( this.beanFactory.isSingleton(beanName)) {
  37. throw new IllegalArgumentException( "Bean with name '" + beanName +
  38. "' is a singleton, but aspect instantiation model is not singleton");
  39. }
  40. MetadataAwareAspectInstanceFactory factory =
  41. new PrototypeAspectInstanceFactory( this.beanFactory, beanName);
  42. this.aspectFactoryCache.put(beanName, factory);
  43. advisors.addAll( this.advisorFactory.getAdvisors(factory));
  44. }
  45. }
  46. }
  47. this.aspectBeanNames = aspectNames;
  48. return advisors;
  49. }
  50. }
  51. }
  52. if (aspectNames.isEmpty()) {
  53. return Collections.emptyList(); //没有,则返回空
  54. }
  55. List<Advisor> advisors = new ArrayList<>(); //缓存中有通知(Advisor) 从缓存中获取并返回
  56. for (String aspectName : aspectNames) {
  57. List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
  58. if (cachedAdvisors != null) {
  59. advisors.addAll(cachedAdvisors);
  60. }
  61. else {
  62. MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
  63. advisors.addAll( this.advisorFactory.getAdvisors(factory));
  64. }
  65. }
  66. return advisors;
  67. }
  • 解析findCandidateAdvisors 步骤 3.getAdvisors

org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors


  
  1. public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
  2. Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //获取标识了@AspectJ标志的切面类
  3. String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //获取切面的名称
  4. validate(aspectClass);
  5. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
  6. new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
  7. List<Advisor> advisors = new ArrayList<>();
  8. for (Method method : getAdvisorMethods(aspectClass)) { //获取切面类中的所有除了切点(@Pointcut注解)的方法,包括object方法
  9. Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); // 每个method获取通知(advisor) 源码
  10. if (advisor != null) {
  11. advisors.add(advisor);
  12. }
  13. }
  14. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
  15. Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
  16. advisors.add( 0, instantiationAdvisor);
  17. }
  18. // Find introduction fields.
  19. for (Field field : aspectClass.getDeclaredFields()) {
  20. Advisor advisor = getDeclareParentsAdvisor(field);
  21. if (advisor != null) {
  22. advisors.add(advisor);
  23. }
  24. }
  25. return advisors;
  26. }
  27. //org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor
  28. public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
  29. int declarationOrderInAspect, String aspectName) {
  30. validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
  31. //获取切点表达式 源码
  32. AspectJExpressionPointcut expressionPointcut = getPointcut(
  33. candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
  34. if (expressionPointcut == null) {
  35. return null;
  36. }
  37. //创建切面的实现类 源码
  38. return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
  39. this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
  40. }
  41. //org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getPointcut
  42. private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
  43. AspectJAnnotation<?> aspectJAnnotation = //获取切面注解 @Before @After。。。。。。
  44. AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); //源码
  45. if (aspectJAnnotation == null) {
  46. return null;
  47. }
  48. //获取切点表达式对象
  49. AspectJExpressionPointcut ajexp =
  50. new AspectJExpressionPointcut(candidateAspectClass, new String[ 0], new Class<?>[ 0]);
  51. ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); //设置切点表达式
  52. if ( this.beanFactory != null) {
  53. ajexp.setBeanFactory( this.beanFactory);
  54. }
  55. return ajexp;
  56. }
  57. /**
  58. *org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#In*stantiationModelAwarePointcutAdvisorImpl
  59. */
  60. public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
  61. Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
  62. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  63. this.declaredPointcut = declaredPointcut;
  64. this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
  65. this.methodName = aspectJAdviceMethod.getName();
  66. this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
  67. this.aspectJAdviceMethod = aspectJAdviceMethod;
  68. this.aspectJAdvisorFactory = aspectJAdvisorFactory;
  69. this.aspectInstanceFactory = aspectInstanceFactory;
  70. this.declarationOrder = declarationOrder;
  71. this.aspectName = aspectName;
  72. if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { //是不是懒加载
  73. // Static part of the pointcut is a lazy type.
  74. Pointcut preInstantiationPointcut = Pointcuts.union(
  75. aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
  76. // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
  77. // If it's not a dynamic pointcut, it may be optimized out
  78. // by the Spring AOP infrastructure after the first evaluation.
  79. this.pointcut = new PerTargetInstantiationModelPointcut(
  80. this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
  81. this.lazy = true;
  82. }
  83. else {
  84. // A singleton aspect.
  85. this.pointcut = this.declaredPointcut;
  86. this.lazy = false;
  87. this.instantiatedAdvice = instantiateAdvice( this.declaredPointcut); //实例化切面 源码
  88. }
  89. }
  90. /**
  91. *org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvice
  92. *
  93. */
  94. public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
  95. MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
  96. Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //1.找到候选的切面类
  97. validate(candidateAspectClass);
  98. AspectJAnnotation<?> aspectJAnnotation =
  99. AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); //找到方法上的注解
  100. if (aspectJAnnotation == null) {
  101. return null;
  102. }
  103. // If we get here, we know we have an AspectJ method.
  104. // Check that it's an AspectJ-annotated class
  105. if (!isAspect(candidateAspectClass)) {
  106. throw new AopConfigException( "Advice must be declared inside an aspect type: " +
  107. "Offending method '" + candidateAdviceMethod + "' in class [" +
  108. candidateAspectClass.getName() + "]");
  109. }
  110. if (logger.isDebugEnabled()) {
  111. logger.debug( "Found AspectJ method: " + candidateAdviceMethod);
  112. }
  113. AbstractAspectJAdvice springAdvice;
  114. //判断注解的类型
  115. switch (aspectJAnnotation.getAnnotationType()) {
  116. case AtPointcut: //是切点的返回null
  117. if (logger.isDebugEnabled()) {
  118. logger.debug( "Processing pointcut '" + candidateAdviceMethod.getName() + "'");
  119. }
  120. return null;
  121. case AtAround: //是不是环绕通知
  122. springAdvice = new AspectJAroundAdvice(
  123. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  124. break;
  125. case AtBefore: //是不是后置通知
  126. springAdvice = new AspectJMethodBeforeAdvice(
  127. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  128. break;
  129. case AtAfter: //后置通知
  130. springAdvice = new AspectJAfterAdvice(
  131. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  132. break;
  133. case AtAfterReturning: //返回通知
  134. springAdvice = new AspectJAfterReturningAdvice(
  135. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  136. AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
  137. if (StringUtils.hasText(afterReturningAnnotation.returning())) {
  138. springAdvice.setReturningName(afterReturningAnnotation.returning());
  139. }
  140. break;
  141. case AtAfterThrowing: //是不是异常通知
  142. springAdvice = new AspectJAfterThrowingAdvice(
  143. candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
  144. AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
  145. if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
  146. springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
  147. }
  148. break;
  149. default:
  150. throw new UnsupportedOperationException(
  151. "Unsupported advice type on method: " + candidateAdviceMethod);
  152. }
  153. // Now to configure the advice...
  154. springAdvice.setAspectName(aspectName);
  155. springAdvice.setDeclarationOrder(declarationOrder);
  156. String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod); //获取方法的参数列表名称
  157. if (argNames != null) {
  158. springAdvice.setArgumentNamesFromStringArray(argNames); //为切面设置参数
  159. }
  160. springAdvice.calculateArgumentBindings();
  161. return springAdvice;
  162. }

org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply


  
  1. public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
  2. if (candidateAdvisors.isEmpty()) {
  3. return candidateAdvisors;
  4. }
  5. List<Advisor> eligibleAdvisors = new ArrayList<>();
  6. for (Advisor candidate : candidateAdvisors) { //遍历候选的通知 把他增加到eligibleAdvisors集合中返回
  7. if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { ////判断是当前的通知是否能用 通过方法匹配来计算当前是否合适当前类的增强器 源码
  8. eligibleAdvisors.add(candidate);
  9. }
  10. }
  11. boolean hasIntroductions = !eligibleAdvisors.isEmpty();
  12. for (Advisor candidate : candidateAdvisors) {
  13. if (candidate instanceof IntroductionAdvisor) {
  14. // already processed
  15. continue;
  16. }
  17. if (canApply(candidate, clazz, hasIntroductions)) {
  18. eligibleAdvisors.add(candidate);
  19. }
  20. }
  21. return eligibleAdvisors;
  22. }

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy


  
  1. protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
  2. @Nullable Object[] specificInterceptors, TargetSource targetSource) {
  3. if ( this.beanFactory instanceof ConfigurableListableBeanFactory) { //判断类型
  4. AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
  5. }
  6. ProxyFactory proxyFactory = new ProxyFactory(); //创建代理工厂
  7. proxyFactory.copyFrom( this);
  8. if (!proxyFactory.isProxyTargetClass()) { //proxyTargetClass 强制使用cglib代理
  9. if (shouldProxyTargetClass(beanClass, beanName)) {
  10. proxyFactory.setProxyTargetClass( true);
  11. }
  12. else {
  13. evaluateProxyInterfaces(beanClass, proxyFactory);
  14. }
  15. }
  16. Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); ////获取容器中的方法通知
  17. proxyFactory.addAdvisors(advisors);
  18. proxyFactory.setTargetSource(targetSource);
  19. customizeProxyFactory(proxyFactory);
  20. proxyFactory.setFrozen( this.freezeProxy);
  21. if (advisorsPreFiltered()) {
  22. proxyFactory.setPreFiltered( true);
  23. }
  24. return proxyFactory.getProxy(getProxyClassLoader()); //获取代理对象 源码
  25. }

流程图

看了以上代码,我们画个加单的图来看一下aop创建代理对象的过程

 


转载:https://blog.csdn.net/qq_38630810/article/details/105565239
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场