Spring AOP
- 它基于动态代理来实现。 如果使用接口,用JDK提供给动态代理来实现,如果没有接口,使用CGLIB实现。
- Spring 3.2以后,spring-core直接把CGLIB和ASM的源码包括进来。
- Spring AOP需要依赖于IOC容器来管理。
- Spring提供了AspectJ的支持,但只用到了切点解析和匹配。
源码
开启aop切面
spring通过@EnableAspectJAutoProxy开启aop切面,在注解类上面发现@Import(AspectJAutoProxyRegistrar.class),AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,所以他会通过registerBeanDefinitions方法为我们容器导入beanDefinition。
解析切面
第一次调用bean的后置处理器回去进行切面的解析。具体解析类是AbstractAutoProxyCreator
,它实现了InstantiationAwareBeanPostProcessor
。进入postProcessBeforeInstantiation
方法。
判断是否应该跳过。真正的解析是在shouldSkip
中。
进入findCandidateAdvisors
的重写方法。
调用super.findCandidateAdvisors()
,去查找实现了Advisor接口的切面类。
1 | kotlin复制代码public List<Advisor> findAdvisorBeans() { |
调用buildAspectJAdvisors
去查找注解方式的切面类。
1 | kotlin复制代码/** |
getAdvisors方法
1 | scss复制代码@Override |
getAdvisor方法
1 | scss复制代码public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, |
getPointcut方法
1 | typescript复制代码private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { |
InstantiationModelAwarePointcutAdvisorImpl函数
1 | kotlin复制代码public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, |
instantiateAdvice方法
1 | kotlin复制代码private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) { |
getAdvice源码
1 | java复制代码public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, |
applyBeanPostProcessorsBeforeInstantiation
到这里第一次调用后置处理器完成了切面的解析那么接下来即调用切面创建动态代理,创建动态代理实在初始化Bean后才调用,即在doCreateBean
的时候回去初始化Bean,initializeBean
方法中才去调用applyBeanPostProcessorsAfterInitialization
方法创建动态代理。
applyBeanPostProcessorsAfterInitialization方法
1 | typescript复制代码public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) |
postProcessAfterInitialization方法(AbstractAutoProxyCreator类实现)
1 | less复制代码public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { |
wrapIfNecessary方法
1 | kotlin复制代码protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { |
createProxy方法创建动态代理
1 | less复制代码protected Object createProxy(Class<?> beanClass, @Nullable String beanName, |
getProxy方法
1 | less复制代码public Object getProxy(@Nullable ClassLoader classLoader) { |
createAopProxy方法
1 | arduino复制代码/** |
getProxy方法有两种实现,CGLIB和JDK动态代理。
到这里就已经创建了AOP动态代理,那么在调用的时候,就会进入到JdkDynamicAopProxy
的invoke
方法。
invoke方法
1 | kotlin复制代码public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { |
通过责任链调用。
ReflectiveMethodInvocation
的proceed方法
1 | kotlin复制代码public Object proceed() throws Throwable { |
本文转载自: 掘金