您现在的位置是:首页 > 正文

Spring框架注解开发——史上最清晰总结Aop原理(超详细)

2024-02-01 00:18:43阅读 2

  Aop原理:【看给容器中注册了什么组件,这个组件怎么工作的,这个组件有什么功能】

1)我们通过使用@EnableAspectJAutoProxy注解开启Aop功能

1.1实际上导入的是AspectJautoProxyRegistar

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}

1.2 这个类中继承了ImportBeanDefinitionRegistrar接口,这个接口可以自定义容器中来注册Bean        


public interface ImportBeanDefinitionRegistrar {
    void registerBeanDefinitions(AnnotationMetadata var1, BeanDefinitionRegistry var2);
}

1.3 一开始先判断 假如容器中包含internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");  if(registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator"))

1.4 通过创建一个Bean AnnotationAwareAspectJAutoProxyCreator

名为:internalAutoProxyCreator,注册在registry中        

} else {
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", -2147483648);
    beanDefinition.setRole(2);
    registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
    return beanDefinition;
}

这里我们来研究一下AnnotationAwareAspectJAutoProxyCreator的继承关系

AnnotationAwareAspectJAutoProxyCreator

      AspectJAwareAdvisorAutoProxyCreator

          AbstractAdvisorAutoProxyCreator

                  AbstractAutoProxyCreator

                        ProxyProcessorSupport 并实现了SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware接口方法(后置处理器)

2) 我们给SetBeanFactory方法,和后置处理器打上断点开始测试

3)@EnableAspectJAutoProxy会给容器中创建一个组件     AnnotationAwareAspectJAutoProxyCreate

AnnotationAwareAspectJAutoProxyCreate 是一个后置处理器

4)容器的创建流程

4.1 创建容器

利用AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext  进入创建IOC容器,进入源码

4.2 调用refresh方法

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    this();
    this.register(annotatedClasses);
    this.refresh();
}

4.3 通过调用registerBeanPostProcessor注册Bean的后置处理器,拦截Bean的创建

try {
    this.postProcessBeanFactory(beanFactory);
    this.invokeBeanFactoryPostProcessors(beanFactory);
    this.registerBeanPostProcessors(beanFactory);
    this.initMessageSource();
    this.initApplicationEventMulticaster();
    this.onRefresh();
    this.registerListeners();
    this.finishBeanFactoryInitialization(beanFactory);
    this.finishRefresh();
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false)

  

4.4 先获取Ioc容器已经定义了需要的BeanPostProcessor(后置处理器)

通过PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this)方法注册

1)先获取Ioc容器已经定义的需要创建所有BeanPostProcessor

2)给容器中添加BeanPostProcessor

3)优先注册实现了priorityOrderedPostProcessors接口的BeanPostProcessor

4)然后再来注册实现了Ordered接口的BeanPostProcessor

5)最后来实现没有优先级接口的BeanPostProcessor

看到这里,肯定很多人问注册是什么呢,这里我们来解释一下,什么叫所谓的注册

通过我箭头这个代码,我们看到了 获取到了ppname的名字internalAutoProxyCreator,看到这个有没有熟悉的感觉,就是我们上面提到的AnnotationAwareAspectJAutoProxyCreator类型

下面我们在来看看他是怎么获取到的吧

调用DogetBean,又调用getSingle(获取单实例bean)

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    return this.doGetBean(name, requiredType, (Object[])null, false);
}

4.5当然我们第一次没有单实例Bean,所以我们获取的肯定会去其他方法 

调用了SingletonFactory的方法,来创建一个Bean

try {
    singletonObject = singletonFactory.getObject();
    newSingleton = true;
}

创建好Bean的实例,在实例化populateBean(对于Bean的属性赋值)

try {
    this.populateBean(beanName, mbd, instanceWrapper);
    if (exposedObject != null) {
        exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    }

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

 4.6 我们的后置处理器,就是在Bean的初始化前后工作的

现在我们再来看看初始化Bean的流程

 调用this.invokeAwareMethods(beanName, bean)方法

判断是属于什么Bean的接口调用什么方法(处理接口回调)

private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware)bean).setBeanName(beanName);
        }

        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
        }

        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware)bean).setBeanFactory(this);
        }
    }

当然我们的internalAutoProxyCreator属于BeanFactoryAware接口中的,则我们会调用setBeanFactory方法

4.7 我们现在先不进去setBeanFactory方法,先来看看执行invoke后会执行什么 

我们会调用applyBeanPostProcessorsBeforeInitialization方法(应用后置处理器的Before)

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}

 其实看完就很清晰的知道,就是遍历所有Bean的后置处理器的postProcessBeforeInitialization


    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if (!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        } while(result != null);

        return result;
    }

4.8 然后执行this.invokeInitMethods(beanName, wrappedBean, mbd)(自定义初始化方法)

4.9 执行完初始化后,我们又在执行applyBeanPostProcessorsAfterInitialization

if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if (!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);

        return result;
    }

我们也可以发现这个跟前置通知是一样的,把所有Bean的后置处理器遍历一遍

我们在回到我们的 4.6 进去到invokeAwareMethods方法中,因为我们是BeanFactoryAware

所以调用的是SetBeanFactory方法

我们创建的是AnnotationAwareAspectJAutoProxyCreator对象,但调用的是父类的AbstractAutoProxyCreator类的setBeanFactory方法

    public void setBeanFactory(BeanFactory beanFactory) {
        super.setBeanFactory(beanFactory);
        if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
            throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
        } else {
            this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
        }
    }

 注意这里我们要调用initBeanFactory方法,这就会回到我们上面分析的AnnotationAwareAspectJAutoProxyCreator的初始化方法

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.initBeanFactory(beanFactory);
    if (this.aspectJAdvisorFactory == null) {
        this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
    }

    this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

 成功创建aspectJAdvisorFactory,aspectJAdvisorsBuilder

把BeanPostProcessor注册到BeanFactory中 

这以上就是我们创造和注册AnnotationAwareAspectJautoProxyCreator 

下面我们来看看 AnnotationAwareAspectJautoProxyCreator 做了些什么

根据上面的分析,我们知道AnnotationAwareAspectJautoProxyCreator 是=》internalAutoProxyCreator 类型的处理器

在根据源码我们来探究

前面还是一样创建IOC容器

调用Refresh方法

但是第三步的时候,我们就不是调用register注册方法,而是初始化剩下的单实例bean

try {
    this.postProcessBeanFactory(beanFactory);
    this.invokeBeanFactoryPostProcessors(beanFactory);
    this.registerBeanPostProcessors(beanFactory);
    this.initMessageSource();
    this.initApplicationEventMulticaster();
    this.onRefresh();
    this.registerListeners();
    this.finishBeanFactoryInitialization(beanFactory);
    this.finishRefresh();

 通过以下的集合和迭代器,我们也大概猜到要干吗了

没错就是遍历获取容器中的Bean,依次创建对象(getBean(beanname))

List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();

getBean——>dogetBean——>getsingle

下面我们来看看怎么创建Bean

   1)先从缓存中获取当前Bean,如果能获取到,说明当前Bean已经被创建过

,如果不能获取,就用我们上面的getBean——>dogetBean——>getsingle方法创建Bean

2)只要创建好的Bean都会被缓存起来

.下面我们来看看创建Bean的流程        

if (mbd.isSingleton()) {
    sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
        public Object getObject() throws BeansException {
            try {
                return AbstractBeanFactory.this.createBean(beanName, mbd, args);
            } catch (BeansException var2) {
                AbstractBeanFactory.this.destroySingleton(beanName);
                throw var2;
            }
        }
    });

假如我们的是单实例的Bean,就返回AbstractBeanFactory.createBean方法中

让我们继续进去看看是怎么创建

Object beanInstance;
try {
    beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
    if (beanInstance != null) {
        return beanInstance;
    }
} catch (Throwable var8) {
    throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
}

beanInstance = this.doCreateBean(beanName, mbdToUse, args);

如果我们的Bean能返回我们的代理对象,那就返回到beanInstance 

如果不能,就调用下面的doCreateBean方法 

这个doCreate方法跟我们的上面一模一样

1)创建Bean的实例

2)this.populateBean(beanName, mbd, instanceWrapper)然后populate给Bean的属性赋值

3)然后再来初始化Bean

exposedObject = this.initializeBean(beanName, exposedObject, mbd);

4)初始化Bean的时候,要执行Aware接口

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(new PrivilegedAction<Object>() {
            public Object run() {
                AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                return null;
            }
        }, this.getAccessControlContext());
    } else {
        this.invokeAwareMethods(beanName, bean);
    }

5)因为我们的Bean属于BeaFactoryAwre,所以执行setBeanFactory方法

private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware)bean).setBeanName(beanName);
        }

        if (bean instanceof BeanClassLoaderAware) {
            ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
        }

        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware)bean).setBeanFactory(this);
        }
    }

6)然后再执行invokeAwareMethods方法前,执行后置处理器的Before

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
    wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}

7)在执行前面的初始化方法

try {
    this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
    throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}

8)最后在执行后置处理器的After

    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

整个流程就是我们上面创建Bean的流程

当然我们是已经创建过了,现在就直接进入resolveBeforeInstantiation方法中

1)后置处理器先尝试返回对象

if (targetType != null) {
    bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

拿到所有的后置处理器,如果后置处理器是InstantiationAwareBeanPostProcessor

如果是就执行后置处理器的postProcessBeforeInstantiation(beanClass, beanName)方法

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    Iterator var3 = this.getBeanPostProcessors().iterator();

    while(var3.hasNext()) {
        BeanPostProcessor bp = (BeanPostProcessor)var3.next();
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }

这里是不是大家有个疑惑,怎么会在这里调用Before的方法呢,不是在我们前面就有调用Before后置处理器的方法呢

这是因为我们前面的是initializeBean(初始化Bean)

但这边是我们的InstantiationAwareBeanPostProcessor后置处理器(实例化Bean)

就是我们的AnnotationAwareAspectJautoProxyCreator 

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    Object postProcessBeforeInstantiation(Class<?> var1, String var2) throws BeansException;

    boolean postProcessAfterInstantiation(Object var1, String var2) throws BeansException;

    PropertyValues postProcessPropertyValues(PropertyValues var1, PropertyDescriptor[] var2, Object var3, String var4) throws BeansException;
}
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

Instantiation表示实例化:实例化的意思在对象还未生成,

Initialization表示初始化:初始化的意思在对象已经生成

前面我们看到的是doCreateBean,这个是在我们创建doCreateBean之前调用,希望返回用后置处理器返回对象

if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);

说明这个AnnotationAwareAspectJautoProxyCreator 会在任何Bean创建之前,会有一个拦截器

都会去调用postProcessBeforeInstantiation方法,尝试返回一个对象

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    Object cacheKey = this.getCacheKey(beanClass, beanName);
    if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }

        if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

接下来我们来看看postProcessBeforeInstantiation这个方法做了什么事情(前置)

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    Object cacheKey = this.getCacheKey(beanClass, beanName);
    if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }

首先先判断Bean是否在advisedBeans

当然现在我们没有处理过这些Bean当然不在其中(增强器) 

if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return null;
}

然后我们在判断是不是会基础类型的Bean和是不是基础类型的切面或者有加@Aspect注解

if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return null;
}
protected boolean isInfrastructureClass(Class<?> beanClass) {
    boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
    if (retVal && this.logger.isTraceEnabled()) {
        this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
    }

    return retVal;        
}

在下来判断是否需要跳过(shouldskip)

 先来获取到我们的增强器(切面的通知方法)

List<Advisor> candidateAdvisors = findCandidateAdvisors();

我们的增强器是InstantiationModelAwarePointcutAdvisor

if (advisor instanceof AspectJPointcutAdvisor) {
   if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
      return true;
   }
}

 判断我们的增强器是不是AspectJPointcutAdvisor类型

 所以我们直接跳过这边返回false

调用完前面的postProcessBeforeInstantiation

现在我们来创建下一个对象postProcessAfterInitialization

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (!this.earlyProxyReferences.contains(cacheKey)) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

这里最重要的方法就是wrapIfNecessary (包装) 

if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
   return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
   return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

这一段又是跟前面一样判断是不是基础类型或者前面,还有是否要跳过

// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
   this.advisedBeans.put(cacheKey, Boolean.TRUE);
   Object proxy = createProxy(
         bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
   this.proxyTypes.put(cacheKey, proxy.getClass());
   return proxy;
}

1)先来获取到当前Bean的所有增强器(通知方法)

就是我们切面定义的四个通知方法,可以应用的增强 器

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

先把四个通知放到一个集合里面

protected List<Advisor> findAdvisorsThatCanApply(
      List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

   ProxyCreationContext.setCurrentProxiedBeanName(beanName);
   try {
      return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
   }
   finally {
      ProxyCreationContext.setCurrentProxiedBeanName(null);
   }
}

调用AOP工具类里面的找到所有的通知方法

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
   if (candidateAdvisors.isEmpty()) {
      return candidateAdvisors;
   }
   List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
         eligibleAdvisors.add(candidate);
      }
   }

在Aop工具中,先判断每一个增强器是不是为candidateAdvisors类型的

    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
   for (Advisor candidate : candidateAdvisors) {
      if (candidate instanceof IntroductionAdvisor) {
         // already processed
         continue;
      }
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

这边又来判断我们增强器是不是IntroductionAdvisor类型的 

在判断是否能用canApply(candidate, clazz, hasIntroductions)

当然我们这四个方法都是能用的

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   if (advisor instanceof IntroductionAdvisor) {
      return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
   }
   else if (advisor instanceof PointcutAdvisor) {
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      return canApply(pca.getPointcut(), targetClass, hasIntroductions);
   }
   else {
      // It doesn't have a pointcut so we assume it applies.
      return true;
   }

把这四个能用的方法都加载到eligibleAdvisor

 找到所有增强器后,对所有增强器进行了一个排序(调用通知方法的顺序)

if (!eligibleAdvisors.isEmpty()) {
   eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}

然后把这些排序好的增强器放在 Object[] specificInterceptors数组里

    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

保存当前Bean在adviseBean中,表示已经被增强处理

如果当前Bean需要增强,需要创建当前Bean的代理对象

下面我们来看一下代理对象创建Bean的过程

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
   proxyFactory.setPreFiltered(true);
}

return proxyFactory.getProxy(getProxyClassLoader());

1)还是获取所有增强器的Bean(通知方法)

2)保存到proxyFactory中(代理工厂)

public Object getProxy(ClassLoader classLoader) {
   return createAopProxy().getProxy(classLoader);
}

创建Aop代理对象

一共会有二种形式的代理对象

一个是JDK 动态代理

一个是Cglib 动态代理

mathCaluator.div        

目标方法执行:

1)这个wrap方法我们调用完了,最终我们给容器中返回了当前组件使用的Cligb增强的代理对象

2)调用AopUtils工具中的intercept方法

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
   Object oldProxy = null;
   boolean setProxyContext = false;
   Class<?> targetClass = null;
   Object target = null;

3)获取拦截器链

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

4)如果没有拦截器链,直接执行目标方法

if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
   // We can skip creating a MethodInvocation: just invoke the target directly.
   // Note that the final invoker must be an InvokerInterceptor, so we know
   // it does nothing but a reflective operation on the target, and no hot
   // swapping or fancy proxying.
   Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
   retVal = methodProxy.invoke(target, argsToUse);
}

5)如果有拦截器链,把拦截器链,执行目标方法的对象,目标方法等所有信息

并调用proceed方法

retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

我们来看看proceed方法流程

1)创建一个List interceptorlist集合,保存所有拦截器

List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);

2)一共有5个,一个默认ExposeInvocationInterceptor.ADVISOR的和四个增强器

3)遍历所有的增强器,将其转为interceptors

for (Advisor advisor : config.getAdvisors()) {
   if (advisor instanceof PointcutAdvisor) {
      // Add it conditionally.
      PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
      if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
         MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
         MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
         if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
            if (mm.isRuntime()) {
               // Creating a new object instance in the getInterceptors() method
               // isn't a problem as we normally cache created chains.
               for (MethodInterceptor interceptor : interceptors) {
                  interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
               }
            }
            else {
               interceptorList.addAll(Arrays.asList(interceptors));
            }
         }
      }

 将转换器转为List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);

 如果是MethodInterceptor那就直接添加到集合中

如果不是AdvisorAdapte(增强器适配器),将增强器转为MethodInterceptor

 转换完成后,返回并添加到集合中

//断点public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
   List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
   Advice advice = advisor.getAdvice();
   if (advice instanceof MethodInterceptor) {
      interceptors.add((MethodInterceptor) advice);
   }
   for (AdvisorAdapter adapter : this.adapters) {
      if (adapter.supportsAdvice(advice)) {
         interceptors.add(adapter.getInterceptor(advisor));
      }
   }
   if (interceptors.isEmpty()) {
      throw new UnknownAdviceTypeException(advisor.getAdvice());
   }
   return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}

我们来在我们上面打上断点后开始测试,先跳过默认的从第二个开始

1)现在进来的是我们的LogException方法(异常方法)

判断是不是MethodInterceptor接口,返回的是true,说明是这个接口,直接添加进集合中去

2)现在进来的是我们的LogReturn方法

判断是不是MethodInterceptor接口,返回的是false,则进入下面的方法 

这底下有三个AdvisorAdapter(增强适配器)

第一个先来调用我们的MethodBefore方法,发现不是

又来调用我们的AfterReturnning的方法

因为我们的LogReturn属于supportAdvice中

if (adapter.supportsAdvice(advice)) {
   interceptors.add(adapter.getInterceptor(advisor));
}

3)第三个进来的为logEnd方法

LogEnd属于MethodInterceptor方法中,所以直接被添加到集合中

4)第四个进来的为logStart方法

判断是不是MethodInterceptor接口,返回的是false,则进入下面的方法 

第一个先来调用我们的MethodBefore方法,发现是属于这个方法中

public MethodInterceptor getInterceptor(Advisor advisor) {
   MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
   return new MethodBeforeAdviceInterceptor(advice);
}

我们进去看这个方法发现,其实就是直接给这个方法包装一个Interceptor而已

然后就添加到集合中

 我们发现已经把全部增强器转换为MethodInterceptor(方法拦截器)

拦截器链(每一个通知方法又被包装成方法拦截器,利用MethodInterceptor机制)

比如通过@EnablAspectJAutoProxy创建的internalAutoProxyCreator

 通过finishBeanFactoryInitialization方法创建其他所有的单实例Bean

创建业务逻辑组件和切面组件(@Before,@After,@AfterReturning,@AfterThrowing)

六——执行目标方法 

 Cglib.intercept会得到目标方法的拦截器链(增强器Advisor)

利用拦截器的链式机制依次进入每一个拦截器,进行执行 

根据栈的方式,先进后出 

如果是Spring4

正常执行:前置通知——>目标方法——>后置通知——>返回通知

异常执行   前置通知——>目标方法——>后置通知——>异常通知

Spring5

正常执行:前置通知——>目标方法——>返回通知——>后置通知

异常执行   前置通知——>目标方法——>异常通知——>后置通知

网站文章

  • socket协议 & socket函数

    Socket协议的形象描述  socket的英文原义是“孔”或“插座”。在这里作为4BDS UNIX的进程通信机制,取后一种意思。socket非常类似于电话插座。以一个国家级电话网为例。电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于socket号。任何用户在通话之前,首先要占有一部电话机,...

    2024-02-01 00:18:36
  • 【MySQL】表的增删查改(初阶)

    【MySQL】表的增删查改(初阶)

    单行数据+全列插入;多行数据+指定列插入;一次插入多个数据;全列查询;指定列查询;查询字段为表达式;别名 AS;去重查询 DISTINCT;排序查询 ORDER BY;条件查询 WHERE;时间的插入与查询;模糊查询;NULL的查询;分页查询LIMIT;修改;删除

    2024-02-01 00:18:09
  • 小白聊智慧制造之十四:一文轻松读懂边缘计算

    小白聊智慧制造之十四:一文轻松读懂边缘计算

    大概很多人都有这样的经历:不小心,手被火烧或被开水烫了,人会立即移开自己的手,这个反应是人的自组织条件反射反应。我们假设一下,如果我们的手被火烧或被开水烫由我们大脑根据汇集的信息做反应决定,再采取行动的话,那会是一个什么样的场景? 假设我们把人的条件反射标记为边缘计算,把人的大脑的反应标记为云计算的话,那么我们就可以浅显而又深刻地了解边缘计算和云计算的区别。 一、什么是边缘计算 边缘计算...

    2024-02-01 00:17:57
  • 获取两个Set集合的并集、差集、交集、补集、对称差集

    代码:public class Test { public static void main(String[] args) { Set<String> a = new HashSe...

    2024-02-01 00:17:50
  • 【GO】入门踩坑记录

    【GO】入门踩坑记录

    目录 1. 编译器 2. PROXY代理 设置 2.1. 设置proxy源 2.2. 处理冲突 3. go工程 3.1. 目录结构 3.2. 处理 github库 依赖 4. 编译 4.1. linu...

    2024-02-01 00:17:21
  • shell 月末

    shell 月末TX_DATE='2020-05-29'MON_LAST_DAY=$(date -d "$(date -d "$(date -d ${TX_DATE} +%Y-%m-01) 1 mon...

    2024-02-01 00:17:15
  • 算法(一)兔子问题

    兔子问题 有一对兔子,从出生三个月后每个月都生一对兔子,小兔子长到第三个月也会生一对兔子,如果兔子都不死,问每个月的兔子的数量为多少? 我们来分析一下这个问题:第一个月兔子为1对,第二个月兔子为1对,...

    2024-02-01 00:17:09
  • 蓝桥杯51小练习--简易计算器

    蓝桥杯51小练习--简易计算器

    0x00 前言 有一段时间没写51的单片机了,实验室的学长留了个小练习,我就用来当“复健”了。一个极其简易的计算器,看起来很简单,但有些细节也是琢磨了一下的(俺还是菜),用的是蓝桥杯的板子,代码的质量着实堪忧。0x01 题目小练习:简易计算器初始显示界面使用16个按键每个按键对应的值为0 1 2 34 5 6 78 9 + ...

    2024-02-01 00:16:40
  • MD5算法-哈希算法

    MD5算法 哈希算法 MD5算法具有以下特点: 1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。 2、容易计算:从原数据计算出MD5值很容易。 3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。 4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。 import java.security.Messa...

    2024-02-01 00:16:33
  • 基于Spring Boot的线程池监控方案

    基于Spring Boot的线程池监控方案

    前言这篇是推动大家异步编程的思想的线程池的准备篇,要做好监控,让大家使用无后顾之忧,敬畏生产。为什么需要对线程池进行监控Java线程池作为最常使用到的并发工具,相信大家都不陌生,但是你真的确定使用对了...

    2024-02-01 00:16:27