Spring笔记(3) - SpringAOP基础详解和源码探究
一.基础
AOP为Aspect Oriented Programming的缩写,面向切面编程,传统的OOP开发中的代码逻辑是至上而下的,在这些至上而下的过程中会产生一些横切性的问题,这些横切性的问题和我们的主业务逻辑关系不大,会散落在代码的各个地方,造成难以维护,AOP的编程思想就是把业务逻辑和横切的问题进行分离,从而达到解耦的目的,使代码的重用性和开发效率高;
AOP是一种编程实现,而SpringAOP是一种实现,Aspect也是一种实现;
SpringAOP和Aspect的区别:
1)SpringAOP的使用语法相对比较复杂,借用Aspect的注解来实现,只是使用了@Aspect注解,底层还是使用SpringAOP的实现;
2)SpringAOP在运行时期进行织入的(动态织入);aspect的注解能在编译时期进行织入的(静态织入);
***对于这个过程,一般分为动态织入和静态织入,动态织入的方式是在运行时动态将要增强的代码织入到目标类中,这样往往是通过动态代理技术完成的,如Java JDK的动态代理(Proxy,底层通过反射实现)或者CGLIB的动态代理(底层通过继承实现),SpringAOP采用的就是基于运行时增强的代理技术;
***ApectJ采用的就是静态织入的方式。ApectJ主要采用的是编译期织入,在这个期间使用AspectJ的acj编译器(类似javac)把aspect类编译成class字节码后,在java目标类编译时织入,即先编译aspect类再编译目标类。
ps:什么时候可以使用Aspect?
当bean没有被容器管理时可以使用,比如第三方框架pojo,当想对这个框架的某个类进行切面管理,但该类不在容器中,就可以使用Aspect语法来实现切面管理;
SpringAOP使用步骤:
1)支持AspectJ语法:@EnableAspectJAutoProxy或<aop:aspectj-autoproxy/>;
2)声明一个切面:@Aspect注册一个bean;
3)声明一个Pointcut切入点表达式;
AOP的术语:
1)Join Point:连接点,目标对象的方法,比如类A有方法B,需要对B进行增加增强方法(log、authority、tx等),B就是连接点,比如上图的login方法;
2)PointCut:切点,连接点的集合,告诉增强方法要增强到哪里去(什么目标类或目标方法),由切入点表达式实现;
-
-
-
- execution(粒度更小):能匹配到参数类型和个数、返回类型、修饰符、包名、类名、方法名等等;
- within:最小只能匹配到类名;
- args:匹配指定参数类型和指定参数数量的方法,与包名和类名无关;
- @args:匹配参数是否使用了指定注解,如果匹配到,对目标方法进行增强通知;
- @target:目标方法使用了指定注解(可以是自定义注解),可以对这些目标方法进行增强通知;
- this:代理对象(当前对象)跟指定类型一致就增强方法;
- @EnableAspectJAutoProxy(proxyTargetClass=false),表示使用JDK动态代理(默认),this指定类型是接口和Proxy,可以匹配到,如果是接口实现类,匹配不到;
- @EnableAspectJAutoProxy(proxyTargetClass=true),表示使用CGLIB代理,this可以匹配到接口实现类;
- target:目标对象跟指定类型一致就增强方法;
- 两个表达式可以一起使用:&&
-
-
-
-
-
- 切面实例化模型:原型,perthis每个切入点表达式匹配的连接点对应的AOP对象都会创建一个新的切面实例,使用@Aspect("perthis(切入点表达式)")指定切入点表达式;
- @Aspect("perthis(this(com.hrh.config.MathCalculator))")指定只对MathCalculator有效进行切面
- 切面实例化模型:原型,perthis每个切入点表达式匹配的连接点对应的AOP对象都会创建一个新的切面实例,使用@Aspect("perthis(切入点表达式)")指定切入点表达式;
-
-
参考:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-pointcuts-examples
3)Advice:通知,主要指什么时候通知和通知到哪里去,前置通知、后置通知等通知就是表示什么时候通知,通知到哪里去就需要结合切入点表达式;
-
-
-
- around环绕通知:ProceedingJoinPoint有proceed方法,可以在proceed方法前后加一些声明形成环绕通知,可以通过该类获取目标方法的参数进行修改;环绕通知一般应用于改变参数;
- ProceedingJoinPoint和JoinPoint的区别:继承了JoinPoint,proceed是aop代理链执行的方法;
- JoinPoint:是一个连接点,在方法参数添加该类可以得到连接点的信息,比如getThis获得代理对象,getTarge获取目标对象;
-
-
4)Weaving:织入,将增强方法添加到目标方法,整合成一个新的代理方法,比如login方法需要log日志方法来增强,所以经过织入形成一个新的方法,里面包含login()、log();
5)target object:目标对象,即原始对象;
6)proxy object:代理对象,目标对象增强后的对象,包含原始对象的代码和增强代码的对象;
二.案例
@EnableAspectJAutoProxy//开启基于注解的aop模式 @Configuration public class AOPConfig { //业务逻辑类加入容器中 @Bean public MathCalculator mathCalculator() { return new MathCalculator(); } //切面类加入容器中 @Bean public LogAspects logAspects() { return new LogAspects(); } } /** * AOP[动态代理]:指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式; * @Aspect 告诉Spring当前类是切面类 */ @Aspect public class LogAspects { /** * 抽取公共的切入点表达式 * 1.本类引用:pointcut() * 2.引用其他切面类:全名【com.hrh.config.LogAspects.pointcut()】 */ @Pointcut("execution(public int com.hrh.config.MathCalculator.*(..))") public void pointcut() { } //在目标方法(div)运行之前运行 @Before("com.hrh.config.LogAspects.pointcut()") public void LogStart(JoinPoint joinPoint) { //获取传入目标方法的参数对象 Object[] args = joinPoint.getArgs(); //Signature getSignature();获取封装了署名信息的对象,在该对象中可以获取到目标方法名,所属类的Class等信息 System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】运行@Before,参数是:" + Arrays.asList(args)); } //在目标方法(div)运行之后运行 @After("pointcut()") public void LogEnd(JoinPoint joinPoint) { System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】运行@After"); } /** * 获得目标方法(div)运行的结果 * @param joinPoint 必须是参数列表第一位,封装了SpringAop中切面方法的信息 * @param result 返回值 */ @AfterReturning(value = "pointcut()", returning = "result") public void LogReturn(JoinPoint joinPoint, Object result) { System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】的返回值:" + result); } //获得目标方法(div)运行的异常信息 @AfterThrowing(value = "pointcut()", throwing = "e") public void LogException(JoinPoint joinPoint, Exception e) { System.out.println("方法名:【" + joinPoint.getSignature().getName() + "】的异常信息:" + e); } } public class MathCalculator { public int div(int i,int j){ return i/j; } } AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AOPConfig.class); MathCalculator bean = context.getBean(MathCalculator.class); bean.div(1, 1);
三.源码探究
-
在探究下面的源码前,带着下面的流程总结进行学习:
-
@EnableAspectJAutoProxy开启AOP功能(SpringBoot会默认开启,所以不需要该注解);
-
@EnableAspectJAutoProxy会给容器注册一个AnnotationAwareAspectJAutoProxyCreator,它是一个后置处理器,会在组件的创建之前进行拦截;
-
容器的创建流程:
-
registerBeanPostProcessors注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator;
-
finishBeanFactoryInitialization初始化剩下的单实例bean;
-
创建业务逻辑组件和切面组件;
-
AnnotationAwareAspectJAutoProxyCreator会拦截组件的创建过程;
-
组件创建完成之后,wrapIfNecessary判断组件是否需要增强;
- 如果是,将通知方法包装成增强器,给目标对象即业务逻辑创建一个代理对象,代理对象有各种增强器;
-
-
-
执行目标方法,调用CglibAopProxy.intercept进行拦截;
-
得到目标方法的拦截器链,利用拦截器的链式机制进行递归,调用proceed()依次进入每一个拦截器进行执行各种通知方法和目标方法;
-
效果:
-
正常执行:前置通知 -> 目标方法 -> 后置通知 -> 返回通知
-
出现异常:前置通知 -> 目标方法 -> 后置通知 -> 异常通知
-
-
-
-
源码
-
@EnableAspectJAutoProxy注解探究,需要启用该注解AOP才会生效
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented //给容器导入AspectJAutoProxyRegistrar @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { boolean proxyTargetClass() default false; boolean exposeProxy() default false; }
-
AspectJAutoProxyRegistrar:AspectJ自动代理注册器,实现了registerBeanDefinitions()自定义给容器注册bean
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //给容器添加AUTO_PROXY_CREATOR_BEAN_NAME=AnnotationAwareAspectJAutoProxyCreator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); .... } } public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); } public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { //注册AnnotationAwareAspectJAutoProxyCreator return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
-
registerOrEscalateApcAsRequired
private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); //registry注册中第一次是不包含AUTO_PROXY_CREATOR_BEAN_NAME=internalAutoProxyCteator,走下面注册代码 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; } //创建获得AnnotationAwareAspectJAutoProxyCreator的定义信息(该对象还没创建),然后注册到容器DefaultListableBeanFactory中,名字叫AUTO_PROXY_CREATOR_BEAN_NAME RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
-
从上面代码可以看出下面的流程:
-
@EnableAspectJAutoProxy注解导入AspectJAutoProxyRegistrar类
-
AspectJAutoProxyRegistrar类最后给容器添加AnnotationAwareAspectJAutoProxyCreator
-
-
下面是AnnotationAwareAspectJAutoProxyCreator:AspectJ自动代理创建器的类关系情况,从中可以看到该类实现了BeanPostProcessor(后置处理器)和BeanFacotryAware(给该类添加BeanFactory组件)对应的方法postProcessBeforeInstantiation()、postProcessAfterInitialization()、setBeanFactory(),所以研究后置处理器在bean创建前后所做的事情和自动装配BeanFactory就可以了。
AnnotationAwareAspectJAutoProxyCreator -> extends AspectJAwareAdvisorAutoProxyCreator -> extends AbstractAdvisorAutoProxyCreator -> extends AbstractAutoProxyCreator -> implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware -> SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor -> InstantiationAwareBeanPostProcessor extends BeanPostProcessor
-
-
开启Debug模式探究AnnotationAwareAspectJAutoProxyCreator的创建和注册实现流程
-
分别在AOPConfig的@Bean注解处、AnnotationAwareAspectJAutoProxyCreator的initBeanFactory()、AbstractAdvisorAutoProxyCreator的setBeanFactory()、AbstractAutoProxyCreator的postProcessBeforeInstantiation()和postProcessAfterInitialization()处打断点
-
方法流程:
- 传入配置类,创建ioc容器;
- 注册配置类,调用refresh刷新容器;
- 注册bean的后置处理器来拦截bean的创建;
- 先从容器中获取已经定义了需要创建对象的BeanPostProcessor;
- 给容器添加其他的BeanPostProcessor;
- 优先注册实现了PriorityOrdered接口的BeanPostProcessor;
- 再给容器注册实现了Ordered接口的BeanPostProcessor;
- 注册其他的BeanPostProcessor;
- 注册BeanPostProcessor,实际就是创建BeanPostProcessor对象(internalAutoProxyCreator),保存在容器中;
- 调用beanFactory.getBean();
- 调用doGetBean(),第一次调用对象是null,需要创建createBean();
- 调用doCreateBean():createBeanInstance创建实例,populateBean()属性赋值,initializeBean()初始化实例;
- initializeBean()初始化实例:
- invokeAwareMethods()设置factoryBean;
- applyBeanPostProcessorsBeforeInitialization()执行所有的postProcessBeforeInitialization方法,即AbstractAutoProxyCreator的postProcessBefforeInstantiation();
- invokeInitMethods()执行自定义初始化方法;
- applyBeanPostProcessorsAfterInitialization()执行所有的postProcessAfterInitialization方法;
- 创建完再次获取对象getSingleton(),加入到bean集合中;
- 创建完获取加入到容器中registerBeanPostProcessors():beanFactory.addBeanPostProcessor(postProcessor);
-
代码流程:
1)AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AOPConfig.class); 2)AnnotationConfigApplicationContext:refresh() 3)AbstractApplicationContext:refresh() @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { ... //注册bean的后置处理器来拦截bean的创建 registerBeanPostProcessors(beanFactory); ... //注册其他BeanPostProcessor finishBeanFactoryInitialization(beanFactory); ... } } 4)PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
5) public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //先从容器中获取已经定义了需要创建对象的BeanPostProcessor,比如下面的值 //org.springframework.context.annotation.internalAutowiredAnnotationProcessor //org.springframework.context.annotation.internalCommonAnnotationProcessor //org.springframework.aop.config.internalAutoProxyCreator【EnableAspectJAutoProxy注解已经定义了给容器添加internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator】 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; //给容器添加其他的BeanPostProcessor beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 分离实现了PriorityOrdered,Ordered和其他接口的BeanPostProcessor List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { //实现了PriorityOrdered(有优先级排序)接口的添加到priorityOrderedPostProcessors中 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); //如果是MergedBeanDefinitionPostProcessor添加到internalPostProcessors中 if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //实现了Ordered接口的添加到orderedPostProcessorNames中 orderedPostProcessorNames.add(ppName); } else { //其他添加到nonOrderedPostProcessorNames中 nonOrderedPostProcessorNames.add(ppName); } } //排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 优先注册实现了PriorityOrdered的BeanPostProcessor registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //然后注册实现了Ordered的BeanPostProcessor List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); //遍历所有的internalAutoProxyCreator[AnnotationAwareAspectJAutoProxyCreator实现了Ordered] for (String ppName : orderedPostProcessorNames) { //获得BeanPostProcessor BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); //注册,加入到beanFactory中 registerBeanPostProcessors(beanFactory, orderedPostProcessors); //注册其他的nonOrderedPostProcessors List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // 最后注册internalPostProcessors sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); } //注册 private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { //遍历加入到beanFactory中 for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); } }
6)beanFactory.getBean: public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } 7)protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { .... // 创建bean实例 if (mbd.isSingleton()) { //第一次获取是null,需要创建实例 sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args);//创建实例 } ... }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } .... } 8)public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { .... try { //获得对象,第一次是null,走createBean方法创建实例,创建完后重新过来获取 singletonObject = singletonFactory.getObject(); newSingleton = true; } .... if (newSingleton) { addSingleton(beanName, singletonObject);//添加到bean集合中 } .... }
9) protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { .... try { //创建实例org.springframework.aop.config.internalAutoProxyCreator Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } .... } 10)protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 定义实例 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args);//创建实例internalAutoProxyCreator } //获得bean实例internalAutoProxyCreator final Object bean = instanceWrapper.getWrappedInstance(); .... // 初始化bean实例 Object exposedObject = bean; try { //对bean进行属性赋值 populateBean(beanName, mbd, instanceWrapper); //初始化实例org.springframework.aop.config.internalAutoProxyCreator exposedObject = initializeBean(beanName, exposedObject, mbd); } .... }
11)protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { .... else { //设置beanFactory invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //执行所有的postProcessBeforeInitialization方法,即AbstractAutoProxyCreator的postProcessBefforeInstantiation() wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd);//执行初始化方法 } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //执行所有的postProcessAfterInitialization方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
12)private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } //设置beanFactory,后面调用AbstractAdvisorAutoProxyCreator的setBeanFactory(),给AbstractAdvisorAutoProxyCreator添加BeanFactory并且初始化BeanFactory if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
-
-
在第3步registerBeanPostProcessors完成AnnotationAwareAspectJAutoProxyCreator的注册后(作为一个后置处理器,接下来探讨它的执行时机),执行finishBeanFactoryInitialization注册其他的Bean,比如internalAutowiredAnnotationProcessor等
-
方法流程:从下面第4步可以看出在创建任何bean之前会进行拦截,获取AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation进行执行
-
finishBeanFactoryInitialization注册其他的bean
-
preInstantiateSingletons遍历容器中所有bean名字,创建对象getBean()
- getBen() -> doGetBean() -> getSingleton()获取单实例 -> createBean()
- doGetBean会从缓存中查找,如果能获取,说明已经被创建过,直接获取,不行再getSingleton()获取单实例 -> createBean()
- create()创建实例前调用resolveBeforeInstantiation进行解析BeforeInstantiation,希望后置处理器能返回一个代理对象,如果能获取返回该bean(AnnotationAwareAspectJAutoProxyCreator)
- 如果第4步解析不能返回bean,调用doCreateBean进行创建
-
-
代码流程:
1) protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { ... /*bean: * org.springframework.context.annotation.internalConfigurationAnnotationProcessor * org.springframework.context.annotation.internalAutowiredAnnotationProcessor * org.springframework.context.annotation.internalCommonAnnotationProcessor * org.springframework.context.event.internalEventListenerProcessor * org.springframework.context.event.internalEventListenerFactory * AOPConfig、mathCalculator、logAspects * org.springframework.aop.config.internalAutoProxyCreator */ .... //实例化其他单实例(上面的bean) beanFactory.preInstantiateSingletons(); }
2) public void preInstantiateSingletons() throws BeansException { .... //获取所有默认的其他bean,即上面注释的bean List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // 遍历容器中所有定义的bean名字 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //是工厂bean if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else {//不是工厂bean getBean(beanName);//获取bean,比如internalEventListenerProcessor } } } for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
3) public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { .... //第一次获取,提前检查单实例缓存中是否已经注入了当前bean(bean只要被创建过,就会被缓存起来)【保证bean只会被创建一次,单实例】 Object sharedInstance = getSingleton(beanName); .... //不在缓存中,进行创建bean else { .... // 创建bean实例 if (mbd.isSingleton()) { //第二次获取,进行创建bean sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } .... }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);//得到bean实例 } } .... }
4) protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { .... try { /** *解析BeforeInstantiation,希望后置处理器能返回一个代理对象,如果能获取返回该bean *从下面的applyBeanPostProcessorsBeforeInstantiation可以看出,在下面创建每个bean之前会尝试获取AnnotationAwareAspectJAutoProxyCreator的实例 */ Object bean = resolveBeforeInstantiation(beanName, mbdToUse);//4.1 if (bean != null) { return bean; } } .... try { //如果不能,创建对象 Object beanInstance = doCreateBean(beanName, mbdToUse, args);//4.2 if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } .... }
4.1) protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; //是否已经提前被解析过 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { //执行before bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { //再执行after bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; } AbstractAutowireCapableBeanFactory: protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { //遍历所有的后置处理器 for (BeanPostProcessor bp : getBeanPostProcessors()) { /** *如果是InstantiationAwareBeanPostProcessor执行postProcessBeforeInstantiation *从上面1.4类关系图可以看出AnnotationAwareAspectJAutoProxyCreator->InstantiationAwareBeanPostProcessor,是在创建bean实例之前先尝试用后置处理器返回对象 * 1.resolveBeforeInstantiation(beanName, mbdToUse) * 2.doCreateBean(beanName, mbdToUse, args) *而BeanPostProcessor是在bean对象创建完成初始化方法前后调用的(可查看initializeBean方法调用情况) */ if (bp instanceof InstantiationAwareBeanPostProcessor) { //如果获取到AnnotationAwareAspectJAutoProxyCreator InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //执行AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
4.2) protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 定义实例 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args);//创建实例internalAutoProxyCreator } //获得bean实例internalEventListenerProcessor final Object bean = instanceWrapper.getWrappedInstance(); .... // 初始化bean实例 Object exposedObject = bean; try { //对bean进行属性赋值 populateBean(beanName, mbd, instanceWrapper); //初始化实例internalEventListenerProcessor exposedObject = initializeBean(beanName, exposedObject, mbd); } .... } protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { .... else { //设置beanFactory invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //执行所有的postProcessBeforeInitialization方法,即AbstractAutoProxyCreator的postProcessBefforeInstantiation() wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd);//对bean执行初始化方法 } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //执行所有的postProcessAfterInitialization方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
-
-
从上面的代码流程可以看到在创建每个bean之前都会调用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation,在上面的案例代码中对AOPConfig的@Bean创建加入容器打下断点,debug探究它的执行流程
-
方法流程
- 判断当前bean是否在advisedBeans中(保存了所有需要增强的bean,即需要切面增强的bean,比如案例代码中的MathCalculator);
- 判断当前类是否是基础类型(Advice、Pointcut、Advisor、AopInfrastructureBean、Aspect切面)和是否需要跳过不处理;
- 对于是否跳过内部的处理逻辑是:获取LogAspects的所有增强方法,比如LogStart、LogEnd等,判断每个增强器是否是AspectJPointctuAdvisor,如果是返回true,否则返回false;
- 在处理完上面的逻辑后,进行bean的创建比如MathCalculator的创建,执行到案例代码中@Bean的new对象创建;
-
代码流程:
//解析比如MathCalculator类、Aspect注解的类 1) public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { //beanClass:class com.hrh.config.MathCalculator //beanName:mathCalculator Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { //判断当前类是否是增强类 if (this.advisedBeans.containsKey(cacheKey)) { return null; } //判断当前类是否是基础类型(Advice、Pointcut、Advisor、AopInfrastructureBean、Aspect切面),是否需要跳过不处理 if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE);//存放基础类logAspects、AOPConfig 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; } return null; }
AbstractAutoProxyCreator: 2) protected boolean isInfrastructureClass(Class<?> beanClass) { //基础类型Advice、Pointcut、Advisor、AopInfrastructureBean boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass); if (retVal && logger.isTraceEnabled()) { logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]"); } return retVal; } AnnotationAwareAspectJAutoProxyCreator: protected boolean isInfrastructureClass(Class<?> beanClass) { //还会判断是否是基础类型和Aspect切面 return (super.isInfrastructureClass(beanClass) || (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass))); } //找到是否有切面注解 public boolean isAspect(Class<?> clazz) { return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz)); } private boolean hasAspectAnnotation(Class<?> clazz) { return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null); }
AspectJAwareAdvisorAutoProxyCreator: 3) protected boolean shouldSkip(Class<?> beanClass, String beanName) { //获得所有的通知方法,比如LogAspects的LogStart、LogEnd等 //通知方法封装的对象candidateAdvisors是InstantiationModelAwarePointcutAdvisor: // expression [com.hrh.config.LogAspects.pointcut()]; advice method [public void com.hrh.config.LogAspects.LogStart(org.aspectj.lang.JoinPoint)]; //判断每个增强器(通知方法)是否是AspectJPointcutAdvisor List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName);//直接返回false }
-
-
从上面的代码第3步的4.1中的resolveBeforeInstantiation可以看出在before后进行bean的创建,后会执行applyBeanPostProcessorsAfterInitialization,debug探究它的执行流程
-
方法流程:
- 如果需要包装调用wrapIfNecessary,即对当前bean比如MathCalculator的方法进行增强方法;
- 获取bean的所有增强器(通知方法)getAdvicesAndAdvisorsForBean;
- findCandidateAdvisors拿到候选的增强器,比如LogAspects的LogStart、LogEnd等4个;
- findAdvisorsThatCanApply找到可以应用到beanClass的增强器,即找到哪些通知方法是可以切入到当前bean方法的;
- canApply使用切入点表达式来匹配当前bean的哪些方法使用增强器;
- 给增强器排序;
- bean已经增强过了,放到缓存advisedBean中;
- createProxy创建代理对象;
- 拿到所有增强器buildAdvisors;
- 放入代理工厂中;
- 得到代理对象,如果没有,创建代理对象;
- 创建代理对象:(如果当前bean实现了接口)JdkDynamicAopProxy创建jdk代理,否则ObjenesisCglibAopProxy创建CGlib代理;
- 给容器返回当前bean经过jdk或CGlib动态代理增强了的对象mathCalculator,即当前bean的每个方法都得到了符合的切面的通知方法,那么以后执行mathCalculator的方法,就会执行获取到的这个代理对象,就会调用增强方法;
-
代码流程:
1) public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { //得到通知方法增强了的MathCalculator对象 Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
//给容器返回当前bean经过jdk或CGlib动态代理增强了的对象 2) public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { //bean:MathCalculator,beanName:mathCalculator Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey);//如果需要则进行包装 } } return bean; }
3) protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && 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; } //获取bean的所有增强器(通知方法) Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);//3.1 if (specificInterceptors != DO_NOT_PROXY) { //当前bean已经增强过了,放到缓存advisedBean中 this.advisedBeans.put(cacheKey, Boolean.TRUE); //创建代理对象 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//3.2 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
//AbstractAdvisorAutoProxyCreator: 3.1) protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { //找到可用的增强器 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY;//返回null } return advisors.toArray(); }
3.1.2) protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //拿到候选的增强器,比如LogAspects的LogStart、LogEnd等4个 List<Advisor> candidateAdvisors = findCandidateAdvisors(); //找到可以应用到beanClass的增强器,即找到哪些通知方法是可以切入到当前bean方法的 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { //对增强器进行排序,即方法调用增强器是有顺序的,先LogStart后LogEnd eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
3.1.3) protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //用AOP工具找到能用的增强器 return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }
3.1.4) public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> 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; } //判断是否能用,如果可以加入到eligibleAdvisors if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
//下面是使用切入点表达式来匹配当前bean的哪些方法使用增强器 3.1.5) 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.2) 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.2.1) public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); } //创建代理对象 protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
//DefaultAopProxyFactory: 3.2.2) 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."); } //如果bean实现了接口使用jdk动态代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config);//创建jdk代理 } return new ObjenesisCglibAopProxy(config);//创建CGlib代理 } else { return new JdkDynamicAopProxy(config); } }
-
-
上面分析了对每个bean根据切入表达式进行了增强方法的封装,创建了一个代理对象,那么接下来来分析MathCalculator.div()的执行路径,在main方法中对bean.div()打断点进行debug分析
-
方法流程:
- 容器中保存了增强后的代理对象,从下图可以看出MathCalculator对象是经过cglib代理过的,这个对象保存了很多信息,比如增强器advisors保存了增强方法、保存了目标对象targetSource等等;
-
调用CglibAopProxy.intercept拦截目标方法执行;
- 调用getInterceptorsAndDynamicInterceptionAdvice将每一个增强器即通知方法包装为拦截器;
- 获取缓存键,根据键值对获取值;
- 缓存如果没有,getInterceptorsAndDynamicInterceptionAdvice进行获取拦截链放入到缓存中;
- List<Object> interceptorList集合保存所有拦截器,长度是所有的增强器的数量,默认+4个增强器;
- 遍历所有增强器,Interceptor[] interceptors = registry.getInterceptors(advisor)将增强器封装到interceptors,然后加入到interceptorList集合中,最后返回interceptorList集合;
- 将advisor转换成interceptors;
- advice【异常通知AspectJAfterThrowingAdvice、后置通知AspectJAfterAdvice】如果是MethodInterceptor,直接加进去interceptors;
- 使用适配器【MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter】遍历,使用增强器适配器将advice【前置通知AspectJMethodBeforeAdvice和后置返回通知AspectAfterReturningAdvice】转换为MethodInterceptor;
- 如果没有拦截器链,直接执行目标方法;
- 如果有,把目标对象、目标方法、拦截器链等参数传递给CglibMethodInvocation进行包装,然后调用proceed();
- 调用getInterceptorsAndDynamicInterceptionAdvice将每一个增强器即通知方法包装为拦截器;
-
代码流程:
//CglibAopProxy.intercept:拦截目标方法执行 1) 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; try { if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } //目标对象:MathCalculator target = getTarget(); if (target != null) { targetClass = target.getClass(); } //根据ProxyFactory获取将要执行的目标方法的拦截器链【将每一个增强器即通知方法包装为拦截器】 //method:div() List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; //如果没有拦截器链,直接执行目标方法 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } else {//如果有,把目标对象、目标方法、拦截器链等参数传递给CglibMethodInvocation,然后调用proceed retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; } finally { if (target != null) { releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
2) public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) { //获取缓存键 MethodCacheKey cacheKey = new MethodCacheKey(method); //根据键值对获取值 List<Object> cached = this.methodCache.get(cacheKey); //缓存如果没有,进行获取拦截链放入到缓存中 if (cached == null) { cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( this, method, targetClass); this.methodCache.put(cacheKey, cached); } return cached; }
3) public List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, Class<?> targetClass) { // This is somewhat tricky... We have to process introductions first, // but we need to preserve order in the ultimate list. //保存所有拦截器,长度是所有的增强器的数量,默认+4个增强器 List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); //遍历所有增强器,将增强器封装到interceptors,然后加入到interceptorList中 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)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } return interceptorList; }
4) public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { //将advisor转换成interceptors List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3); Advice advice = advisor.getAdvice(); //advice【异常通知AspectJAfterThrowingAdvice、后置通知AspectJAfterAdvice】如果是MethodInterceptor,直接加进去interceptors if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); } //使用适配器遍历,使用增强器适配器将advice【前置通知AspectJMethodBeforeAdvice和后置返回通知AspectAfterReturningAdvice】转换为MethodInterceptor //适配器:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter 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()]); }
-
-
上面讲了会将所有的通知方法转换为拦截器链,然后包装到CglibMethodInvocation中,然后调用proceed()执行,下面探究proceed的执行流程即拦截器链的触发过程
-
方法流程:
- 包装后的拦截器链:
- proceed方法每次执行,currentInterceptorIndex会自增+1,根据这个currentInterceptorIndex索引从拦截器链chain中取出拦截器;
- 如果没有拦截器了直接执行目标方法invokeJoinpoint(),比如MathCalculator.div(),如果有拦截器,先根据currentInterceptorIndex从拦截器链取出拦截器,调用MethodInterceptor.invoke执行各种通知方法
- 拦截器的执行是递归的顺序,在捕获到异常时,会直接执行异常通知而跳过返回通知:
-
代码流程:
//DefaultAdvisorAdapterRegistry:每次执行proceed,currentInterceptorIndex会自增1,根据索引从拦截器链中取出拦截器 1) public Object proceed() throws Throwable { // We start with an index of -1 and increment early. //currentInterceptorIndex记录当前拦截器索引,从-1开始,判断当前currentInterceptorIndex是否等于拦截器链的长度-1(5-1=4),如果拦截器链为空,则判断成立 //没有拦截器直接执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(执行到了最后一个拦截器)执行目标方法 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint();//反射直接执行目标方法 } //currentInterceptorIndex+1,从拦截器链中获取索引为0的拦截器ExposeInvocationInterceptor Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { //调用MethodInterceptor.invoke(),执行各种通知方法 return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
2) protected Object invokeJoinpoint() throws Throwable { return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments); } 3) public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) throws Throwable { // Use reflection to invoke the method. try { ReflectionUtils.makeAccessible(method); return method.invoke(target, args);//反射直接执行目标方法 } catch (InvocationTargetException ex) { // Invoked method threw a checked exception. // We must rethrow it. The client won't see the interceptor. throw ex.getTargetException(); } catch (IllegalArgumentException ex) { throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex); } catch (IllegalAccessException ex) { throw new AopInvocationException("Could not access method [" + method + "]", ex); } }
//MethodInvocation放到线程共享中ThreadLocal 4) private static final ThreadLocal<MethodInvocation> invocation = new NamedThreadLocal<MethodInvocation>("Current AOP method invocation"); //ExposeInvocationInterceptor public Object invoke(MethodInvocation mi) throws Throwable { //从线程共享变量ThreadLocal拿出一个MethodInvocation MethodInvocation oldInvocation = invocation.get(); invocation.set(mi);//将MethodInvocation放入ThreadLocal中 try { return mi.proceed();//执行DefaultAdvisorAdapterRegistry的proceed } finally { invocation.set(oldInvocation); } } //AspectJAfterThrowingAdvice public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } catch (Throwable ex) {//拿到抛出的异常 if (shouldInvokeOnThrowing(ex)) { invokeAdviceMethod(getJoinPointMatch(), null, ex);//执行异常通知 } throw ex; } } //AfterReturningAdviceInterceptor public Object invoke(MethodInvocation mi) throws Throwable { Object retVal = mi.proceed();//proceed如果没有问题,执行下面代码,如果有问题,下面通知跳过执行AspectJAfterThrowingAdvice.invoke抛出异常 this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());//执行返回通知 return retVal; } //AspectJAfterAdvice public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { invokeAdviceMethod(getJoinPointMatch(), null, null);//执行后置通知 } } //MethodBeforeAdviceInterceptor public Object invoke(MethodInvocation mi) throws Throwable { //调用之前先输出before前置通知 this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() ); return mi.proceed(); }
-
-
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】。
如果,您对我的博客所讲述的内容有兴趣,请继续关注我的后续博客,我是【码猿手】。