【阅读前提】: 需了解AOP注解开发流程:链接
在配置类中添加注解@EnableAspectJAutoProxy,便开启了AOP(面向切面编程) 功能。此注解也是了解AOP源码的入口。
@EnableAspectJAutoProxy @Configuration public class MainConfigOfAOP {
【1】@EnableAspectJAutoProxy是什么?我们进入注解,查看其源码如下:发现调用EnableAspectJAutoProxy类,同时使用 @Import注解向容器中导入 AspectJAutoProxyRegistrar 组件:作用是给容器中注册自定义的Bean。
@Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy {
【2】进入AspectJAutoProxyRegistrar类,调用registerBeanDefinitions中的register...Necessary方法注册组件。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //向容器(registry)中注入组件 AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
【3】 进入register...Necessary方法,通过源码分析:该方法向容器中注册一个AnnotationAwareAspectJAutoProxyCreator(支持注解模式的面向切面自动代理创建器)组件,其名称为internalAutoProxyCreator。需要注意的是其注册的是一个BeanDefinition(Bean的定义信息,并没有实例化。后续分析时会说到) 。
//debug 进来后,发现cls参数的值等于 AnnotationAwareAspectJAutoProxyCreator 这个参数也是直接写死的,如下:。 //registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); @Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //AUTO_PROXY_CREATOR_BEAN_NAME == internalAutoProxyCreator //因第一次进来,所以容器中不存在 internalAutoProxyCreator if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } //创建一个新的对象封装 cls RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); //将封装的cls对象注册到容器中,并将名称定义为AUTO_PROXY_CREATOR_BEAN_NAME == internalAutoProxyCreator 就上上述判断的语句。 //此时我们就应该分析 AnnotationAwareAspectJAutoProxyCreator对象的作用 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
此自动代理创建器的内部功能,其等价于AOP的主要功能。 此类的继承结构如下:
我们进入自动代理的抽象父类AbstractAutoProxyCreator中发现,其实现了SmartInstantiationAwareBeanPostProcessor后置处理器(在bean初始化前后做一些操作,AOP的特点)和BeanFactoryAware自动装配BeanFactory。
@SuppressWarnings("serial") public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
AOP原理分析技巧:【看给容器中注册了什么组件, 这个组件什么时候工作,这个组件的功能是什么?】,研究透这些,原理也就清楚了。
我们从AbstractAutoProxyCreator父类向AnnotationAwareAspectJAutoProxyCreator子类的顺序,查看其内部关于后置处理器和自动装备的方法并加入断点:
【1】AbstractAutoProxyCreator:包含后置处理器前后的两个方法和自动装配的方法。
//后置处理器相关的方法1 @Override public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } //后置处理器相关的方法2 @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } //自动装备相关的方法 @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; }
【2】AbstractAdvisorAutoProxyCreator:重写了setBeanFactory方法。
//自动装备方法 @Override public void setBeanFactory(BeanFactory beanFactory) { super.setBeanFactory(beanFactory); if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { throw new IllegalArgumentException( "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory); } initBeanFactory((ConfigurableListableBeanFactory) beanFactory); }
【3】对 2中的initBeanFactory方法进行了重写。
@Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.initBeanFactory(beanFactory); if (this.aspectJAdvisorFactory == null) { this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); }
【1】创建 IOC 容器,传入主配置类MainConfigOfAOP
//获取容器中的类 ApplicationContext ApplicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
【2】调用AnnotationConfigApplicationContext构造器:注册配置类和刷新容器(创建容器中的所有Bean,类似于初始化容器)
public AnnotationConfigApplicationContext(Class>... annotatedClasses) { //创建对象 this(); //注册配置类 register(annotatedClasses); //刷新容器 refresh(); }
【3】调用refresh方法:主要查看registerBeanPostProcessors(beanFactory); 方法,其作用是注册bean后置处理器,用方便来拦截bean的创建。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { .... // 注册 bean 后置处理器,用来拦截 bean 的创建 registerBeanPostProcessors(beanFactory); .... }
【4】进入registerBeanPostProcessors调用的方法:先获取 IOC 容器中已经定义了的需要创建对象的所有后置处理器BeanPostProcessor(已定义:指我们在解析配置类的时候@EnableAspectJAutoProxy会为我们注册一个AnnotationAwareAspectJAutoProxyCreator后置处理器的定义,包括默认的一些后置处理器的定义)例如:
上述列表中的internalAutoProxyCreator后置处理器,就是我们分析@EnableAspectJAutoProxy时注入的那个处理器。后置处理的注册分为以下三种情况:
■ 优先注册实现了PriorityOrdered(优先级)接口的BeanPostProcessors;
■ 其次注册实现了Ordered接口的BeanPostProcessors;
■ 注册所有常规Beanpstprocessors;
internalAutoProxyCreator后置处理器实现了Ordered接口。分析代码可知:【根据bean定义名称internalAutoProxyCreator从beanFactory中获取注入的后置处理器】调用的方法 = beanFactory.getBean(ppName, BeanPostProcessor.class);
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //获取ioc容器中已经定义了的需要创建对象的所有 BeanPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //也会注意一些其他后置处理器,bean 是在 beanPostProcessor 实例化期间创建的,即 bean 不适合由所有 beanPostProcessors 处理。这个其实不重要,可以省略... int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); //判断哪些后置处理器配置了优先级 for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } }else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); }else { nonOrderedPostProcessorNames.add(ppName); } } // 优先注册实现了 PriorityOrdered(优先级) 的 BeanPostProcessors sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 其次注册实现了Ordered 接口的 BeanPostProcessors. ListorderedPostProcessors = new ArrayList<>(); for (String ppName : orderedPostProcessorNames) { //根据 bean定义的名称internalAutoProxyCreator 从 beanFactory 中获取注入的后置处理器 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 注册所有常规beanpstprocessors。 List nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // 最后,重新注册所有内部beanpstprocessors。 sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors);
【5】进入上述所说的beanFactory.getBean(ppName, BeanPostProcessor.class); 方法如下:因第一次进入容器,因此获取不到实例。会通过 getSingleton方法创建BeanPostProcessor的实例,并保存到容器中。
@Override publicT getBean(String name, Class requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } //上述方法内部调用的是 doGetBean(name, requiredType, null, false); 代码如下: @SuppressWarnings("unchecked") protected T doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //因为第一次获取,容器中不存在此实例。因此 sharedInstance==null Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { ... }else { // 创建 bean 实例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); }catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } }
【6】创建internalAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator实例。步骤如下:
//1、创建bean的实例 createBean(beanName, mbd, args); //2、给Bean 的各属性赋值 populateBean(beanName, mbd, instanceWrapper); //3、初始化 bean ,比较重要,因为后置处理器就是在此前后进行工作的 exposedObject = initializeBean(beanName, exposedObject, mbd);
【7】重点是:初始化initializeBean方法,查看实现的步骤如下:
//1、调用 invokeAwareMethods 处理Aware 接口的方法回调,beanName=internalAutoProxyCreator 实现了 BeanAware 接口 invokeAwareMethods(beanName, bean); //2、应用后置处理器 BeforeInitialization applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); //3、执行自定义的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); //4、执行后置处理器的 After方法 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); //下面是上述方法的具体实现 //1、invokeAwareMethods 实现如下: private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { //..... //实现了 BeanFactoryAware 接口,因此执行 setBeanFactory. //bean==AnnotationAwareAspectJAutoProxyCreator if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } } //2、applyBeanPostProcessorsBeforeInitialization 实现如下: @Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; //获取所有的后置处理器,执行前置Before 处理器。 for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } //3、invokeInitMethods 方法的具体实现 protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction
【8】执行Aware初始化时,会调用setBeanFactory方法,我们追下去会发现调用的是AbstractAdvisorAutoProxyCreator的setBeanFactory方法(就是我们分析AnnotationAwareAspectJAutoProxyCreator继承关系时的父类 )。
AnnotationAwareAspectJAutoProxyCreator(AbstractAdvisorAutoProxyCreator).setBeanFactory(BeanFactory)line:58
@Override public void setBeanFactory(BeanFactory beanFactory) { //调用父类的 setBeanFactory super.setBeanFactory(beanFactory); if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { throw new IllegalArgumentException( "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory); } //AnnotationAwareAspectJAutoProxyCreator 方法对此进行了重写 initBeanFactory((ConfigurableListableBeanFactory) beanFactory); }
【9】进入initBeanFactory方法,我们知道此方法已被AnnotationAwareAspectJAutoProxyCreator重写:
//位于 AnnotationAwareAspectJAutoProxyCreator 类中 @Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.initBeanFactory(beanFactory); if (this.aspectJAdvisorFactory == null) { //创建了放射的通知工厂 this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); }
【10】最终BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功,将其添加到beanFactory中。
for (String ppName : orderedPostProcessorNames) { //实例 pp==AnnotationAwareAspectJAutoProxyCreator BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //放入 ordered后置处理器集合 orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } //将处理器按优先级排序 sortPostProcessors(orderedPostProcessors, beanFactory); //调用注册方法 registerBeanPostProcessors(beanFactory, orderedPostProcessors); //上述注册方法的内部代码 private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, ListpostProcessors) { //将后置处理器都添加到bean工厂 for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); } }
【1】以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程。接下来就是对创建后的流程进行说明:AnnotationAwareAspectJAutoProxyCreator是继承InstantiationAwareBeanPostProcessor的后置处理器:我们在上面说的IOC容器初始化时,会调用 refresh方法:我们进入此方法看下,我们之前分析registerBeanPostProcessors方法,接下来分析finishBeanFactoryInitialization方法(实例所有剩余的单实例bean)完成BeanFactory初始化工作。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //...... // 注册 bean后置处理器 来拦截 bean 的创建。 registerBeanPostProcessors(beanFactory); //...... // 初始化特定上下文子类中的其他特殊bean。 onRefresh(); //...... // 实例化所有剩余的(非延迟初始化)单例。 finishBeanFactoryInitialization(beanFactory); }
【2】遍历获取容器中所有的Bean,依次创建对象 getBean(beanName); 流程:getBean->doGetBean()->getSingleton(),getBean方法如下:先从缓存中获取当前bean,如果能获取到说明bean是之前被创建过的,直接使用,否则创建bean;只要是创建好的bean都会被缓存起来。
// 先检查单例缓存中是否有已存在手动注册的单例,如果存在说明之前bean已创建 Object sharedInstance = getSingleton(beanName); //缓存中不存在 bean 时才创建该单例 bean if (sharedInstance != null && args == null) { //... }else{ //创建bean实例。 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } }
【2.1】进入创建bean的步骤:createBean方法,首先会调用resolveBeforeInstantiation方法,让beanPostProcessors后置处理器有机会返回代理对象而不是目标bean实例。如果能返回则直接使用,如果不能则调用doCreateBean方法来创建实例。
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { /*现获取类的基本信息 例如: Root bean: class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]; scope=singleton等等*/ RootBeanDefinition mbdToUse = mbd; //...... //让beanPostProcessors有机会返回代理而不是目标bean实例。 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } //通过此方法,先调用 aware、前置处理器、bean初始化、后置处理器 ,之前有分析过。 Object beanInstance = doCreateBean(beanName, mbdToUse, args); }
【BeanPostProcessor是在Bean对象创建完成初始化前后调用的】
【InstantiationAwareBeanPostProcessor是在创建bean实例之前先尝试用后置处理器返回代理对象】
后置处理器与后置处理器不同,具体什么时候调用,需要根据不同情况而定。
【2.1.1】分析resolveBeforeInstantiation方法(让beanPostProcessors有机会返回代理对象):我们分析的AnnotationAwareAspectJAutoProxyCreator就是InstantiationAwareBeanPostProcessor类型的后置处理器。会在任何bean创建之前先尝试返回bean的代理实例。
@Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } //上面两个方法的源码展示 @Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class> beanClass, String beanName) { //获取所有的后置处理器 for (BeanPostProcessor bp : getBeanPostProcessors()) { //如果后置处理器是 InstantiationAwareBeanPostProcessor 类型的处理器则执行 postProcessBeforeInstantiation 方法。 //我们分析的 AnnotationAwareAspectJAutoProxyCreator 就是 InstantiationAwareBeanPostProcessor 类型的处理器 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //***** 后续分析 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
【2.1.1.1】接着分析上述的postProcessBeforeInstantiation方法:内容较多,放在五中分析。
【2.1.2】分析doCreateBean方法,之前有介绍过,我们在看下源码:就是对创建的目标类前后对后置处理器的方法进行初始化。才是真正创建一个bean的实例。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { //创建 bean 实例 instanceWrapper = createBeanInstance(beanName, mbd, args); //bean 属性赋值 populateBean(beanName, mbd, instanceWrapper); //初始化 bean exposedObject = initializeBean(beanName, exposedObject, mbd); } //初始化方法 initializeBean 的源码 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //初始化 aware 接口的类 invokeAwareMethods(beanName, bean); //后置处理器 Before 方法初始化 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); //初始化类 invokeInitMethods(beanName, wrappedBean, mbd); //后置处理器 after 方法初始化 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); //返回创建好的类 return wrappedBean; }
【1】每个bean创建之前,调用此方法。我们主要观察业务逻辑MathCalculator类和切面LogAspects类的创建。
//当bean = MathCalculator or LogAspects 我们着重分析此方法,其他的略过 @Override public Object postProcessBeforeInstantiation(Class> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //判断当前 bean 是否在 advisedBeans 中(保存了所有需要增加的 bean:意思就是添加了切面的内容),第一次进行肯定是不包含的所以会跳过 if (this.advisedBeans.containsKey(cacheKey)) { return null; } //isInfrastructureClass 判断当前类是否为基础类型的,也就是实现了 Advice、Pointcut、Advisor、AopInfrastructureBean //或者是否为切面注解标注的类 (@Aspect),第一个 MathCalculator = false //shouldSkip 是否需要跳过:内部是获取候选的增强器(也就是切面内的通知方法) //将所有的增强器封装成了 List 集合,增强器的类型是 InstantiationModelAwarePointcutAdvisor if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // targetSource = null TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } //直接返回空,进入我们配置类中,创建 MathCalculator 对象 return null; }
【2】上述代码中的shouldSkip源码:
@Override protected boolean shouldSkip(Class> beanClass, String beanName) { //获取所有的增强器 考虑通过缓存方面名称列表进行优化 ListcandidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { //我们的增强器都是 InstantiationModelAwarePointcutAdvisor 类型的,不是AspectJPointcutAdvisor 所以跳过 if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } //父类直接返回 false return super.shouldSkip(beanClass, beanName); }
【3】创建完MathCalculator后,调用postProcessAfterInitialization
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { // cacheKey = calculator Object cacheKey = getCacheKey(bean.getClass(), beanName); //判断之前是否代理过 if (this.earlyProxyReferences.remove(cacheKey) != bean) { //包装目标类,如果需要的话 return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
【3.1】查看包装方法wrapIfNecessary的源码:分析后得出如下结论:以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //...... 省略的都是判断是否为切面类或以代理类 //如果需要就创建代理类 //getAdvicesAndAdvisorsForBean 获取能在当前类使用的增强器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { //保存当前 bean 在advisedBeans 表示当前bean 被处理了 this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建代理对象 ****重点,返回的是一个通过 Cglib 代理的对象 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;
【3.1.1】进入当前类使用的增强器方法:getAdvicesAndAdvisorsForBean
@Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class> beanClass, String beanName, @Nullable TargetSource targetSource) { //获取可用的增强器 Listadvisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
【3.1.1.1】进入获取可用增强器的方法:findEligibleAdvisors
protected ListfindEligibleAdvisors(Class> beanClass, String beanName) { //获取后置增强器 List candidateAdvisors = findCandidateAdvisors(); //找到能在当前bean中使用的增强器(找那些方法能够切入到当前方法的) List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //对增强器进行了排序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; } //上面获取当前bean中使用的增强器的方法源码 protected List findAdvisorsThatCanApply( List candidateAdvisors, Class> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //通过 AopUtils工具类获取所有的通知方法 return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } //工具类方法源码展示 public static List findAdvisorsThatCanApply(List candidateAdvisors, Class> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List eligibleAdvisors = new ArrayList<>(); for (Advisor candidate : candidateAdvisors) { //我们的增强器不是此类型 if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } 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; } //判断是否为可用的增强器的方法 canApply源码: 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; } }
【3.1.2】进入代理对象的创建方法:createProxy
protected Object createProxy(Class> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } //创建代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } //获取所有的增强器,并保存在代理工厂 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()); }
【3.1.2.1】进入代理工厂创建对象的方法proxyFactory.getProxy的源码:
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } //进入 createAopProxy().getProxy 内部的内部方法 @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } //创建 JDK 代理或者 Cglib 代理。如果实现了接口则使用 JDK 代理,否则Cglib 代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
【1】容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如:增强器,目标对象…)
【2】CglibAopProxy.intercept(); 拦截目标方法执行如下:主要是根据ProxyFactory对象获取将要执行的目标方法的拦截器链。
1)、如果没有拦截器链,直接执行目标方法。
2)、如果有拦截器链,吧需要执行的目标对象,目标方法,拦截器链等信息传入创建一个CglibMethodInvocation对象,并调用retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); 方法。
@Override @Nullable public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { Object oldProxy = null; boolean setProxyContext = false; Object target = null; TargetSource targetSource = this.advised.getTargetSource(); try { if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } target = targetSource.getTarget(); Class> targetClass = (target != null ? target.getClass() : null); //根据 ProxyFactory 对象获取将要执行的目标方法的拦截器链 List
【3】 拦截器链:List
1)、List
2)、遍历所有的增强器,将其转为Interceptor(拦截器):registry.getInterceptors(advisor);
@Override public List
3)、将增强器转为MethodInterceptor,转化方式如下:最终返回拦截器链(每一个通知方法又被包装为方法拦截器,后期都是利用MethodInterceptor机制)。
@Override public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { Listinterceptors = new ArrayList<>(3); Advice advice = advisor.getAdvice(); //如果是 MethodInterceptor 直接加入到 list 中 if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } //如果不是则,使用 AdvisorAdapter 将增强器转为 MethodInterceptor 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[0]); }
【4】拦截器链有了之后,创建CglibMethodInvocation并执行proceed方法:
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
【1】拦截器链展示:除了默认的方法ExposeInvocationInterceptor剩下的 4个都是我们切面中的方法。
【2】如果没有拦截器执行目标方法执行代理对象CglibMethodInvocation的proceed方法:
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
【3】进入proceed方法:
@Override @Nullable public Object proceed() throws Throwable { //判断连接器栏的长度是否 == 0,此方法会在拦截器链的最后一个链时调用 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { //执行目标方式,输入为:MathCalculator...div... return invokeJoinpoint(); } //获取下标=0的拦截器 ExposeInvocationInterceptor Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { //下标0 跳过...... } else { // this=ReflectiveMethodInvocation return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
【4】进入[MethodInterceptor] interceptorOrInterceptionAdvice).invoke(this); 方法:会循环调用list中的拦截器,直到后置处理器:AspectJMethodBeforeAdvice
//ThreadLocal 线程共享数据 (共享 MethodInvocation) private static final ThreadLocalinvocation = new NamedThreadLocal<>("Current AOP method invocation"); @Override public Object invoke(MethodInvocation mi) throws Throwable { //获取 invocation MethodInvocation oldInvocation = invocation.get(); //将当前方法,放入 invocation invocation.set(mi); try { //执行 cglib 的proceed() 就获取到了下标为1的拦截器 AspectJAfterThrowingAdvice return mi.proceed(); } finally { //执行后置通知 invocation.set(oldInvocation); } }
【5】 当advice=AspectJMethodBeforeAdvice后置处理器时,invoke方法如下:
@Override public Object invoke(MethodInvocation mi) throws Throwable { //执行后置处理器的 before 方法 //输出如下:div运行。。。@Before:参数列表是:{[2, 3]} this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); //进入上述展示的 processd 方法,此时进入第一个判断语句,执行目标方法 return mi.proceed(); }
【6】 后置处理器的After方法执行的invoke方法展示:最终执行结果的返回方法。
@Override public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { //执行 after 方法:div结束。。。@After invokeAdviceMethod(getJoinPointMatch(), null, null); } }
【7】上述分析的流程图如下:根据链表循环向下执行,当最后一个后置处理器的before执行完成后,进行目标方法,并进行回流执行拦截器的目标方法。