当前位置: 首页>编程语言>正文

Spring 框架使用注解注入中文乱码 spring框架注解实现原理

  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

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

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_java,第1张

通过我箭头这个代码,我们看到了 获取到了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这个方法做了什么事情(前置)

当然现在我们没有处理过这些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)

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_spring_02,第2张

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

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

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_java_03,第3张

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

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 动态代理

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_java_04,第4张

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()]);
}

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

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_后端_05,第5张

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

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

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

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

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_Spring 框架使用注解注入中文乱码_06,第6张

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

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

又来调用我们的AfterReturnning的方法

因为我们的LogReturn属于supportAdvice中

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

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

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_单实例_07,第7张

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

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

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

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

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

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

然后就添加到集合中

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_Spring 框架使用注解注入中文乱码_08,第8张

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

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

比如通过@EnablAspectJAutoProxy创建的internalAutoProxyCreator

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

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

六——执行目标方法 

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

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

根据栈的方式,先进后出 

Spring 框架使用注解注入中文乱码 spring框架注解实现原理,Spring 框架使用注解注入中文乱码 spring框架注解实现原理_Spring 框架使用注解注入中文乱码_09,第9张

如果是Spring4

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

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

Spring5

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

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


https://www.xamrdz.com/lan/5de1937675.html

相关文章: