本篇内容以注解的形式使用Spring AOP,所以这里容器使用的是AnnotationConfigApplicationContext
Spring Ioc容器的加载流程
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
-
首先是this(),此无参构造函数主要完成两件事
- 调用AnnotationConfigApplicationContext的一系列父类的无参构造函数,初始化相关的属性,包括beanFactoryPostProcessors,beanFactory等重要属性;
-
通过AnnotatedBeanDefinitionReader注册内置的postProcessor(实质是把<beanName,BeanDefinition>键值对放入DefaultListableBeanFactory的beanDefinitionMap属性中)
-
AnnotationConfigUtils#registerPostProcessor会注册以下后置处理器
- ConfigurationClassPostProcessor(BeanDefinitionRegistryPostProcessor的实现类,主要解析主配置类、处理@Bean等注解)
- AutowiredAnnotationBeanPostProcessor(SmartInstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor的实现类,本质是BeanPostProcessor)
- CommonAnnotationBeanPostProcessor,设置@PostConstruct和@PreDestroy注解(在父类InitDestroyAnnotationBeanPostProcessor中)
- 如果支持JPA,注册PersistenceAnnotationBeanPostProcessor
- EventListenerMethodProcessor
- DefaultEventListenerFactory
-
- 构造ClassPathBeanDefinitionScanner实例对象(构造函数setResourceLoader,把Spring ioc容器转为ResourceLoader)
-
注册配置类
- 把配置类放入DefaultListableBeanFactory的beanDefinitionMap属性中
- 刷新容器refresh()
-
invokeBeanFactoryPostProcessors(beanFactory),主要完成的功能:往beanDefinitionNames中注册@Bean注解标注的方法返回的对象,如:业务逻辑类,切面类,@Import注解引入的类,
- invokeBeanDefinitionRegistryPostProcessors
参数为上一步获取的后置处理器的bean集合,如:
- 首先从Spring容器中获取ConfigurationClassPostProcessor对应的bean;
- 然后解析配置类,流程是:ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
```
// 创建配置类的解析器
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
// 开始解析
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
// 创建配置类BeanDefinition的解析器
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 解析@Bean注解标注的方法返回的对象,@Import注解引入的类,注入的对象
this.reader.loadBeanDefinitions(configClasses);
```
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions
```
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
// 解析@Bean注解标注的类返回的对象
loadBeanDefinitionsForBeanMethod(beanMethod);
}
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 解析@Import注解引入的类,注入的对象
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
```
- ConfigurationClassParser解析配置类,主要功能是填充configurationClasses属性(key,value都是解析后的ConfigurationClass的实例)
- 解析ConfigurationClass,主要是得到beanMethods,importBeanDefinitionRegistrars属性值
- ConfigurationClassBeanDefinitionReader#loadBeanDefinitions,主要功能是把上面解析得到的beanMethods注册到beanDefinitionMap中,以及调用AspectJAutoproxyRegistrar的registerBeanDefinitions方法,把AnnotationAwareAspectJAutoProxyCreator注册到beanDefinitionMap中
- registerBeanPostProcessors(beanFactory)
- 实例化AnnotationAwareAspectJAutoProxyCreator,并加入AbstractBeanFactory的beanPostProcessors属性中,
- 往单例缓存池中加入internalAutoProxyCreator
-
在获取internalAutoProxyCreator的实例过程中,会调用doCreateBean#setBeanFactory的aware接口,初始化与AOP获取advisors相关的一些类
-总的逻辑;- 初始化BeanFactoryAdvisorRetrievalHelperAdapter对象
- ReflectiveAspectJAdvisorFactory对象(解析切面,并获取advisors集合)
- BeanFactoryAspectJAdvisorsBuilderAdapter(AnnotationAwareAspectJAutoProxyCreator的内部类,其父类是BeanFactoryAspectJAdvisorsBuilder,作用是解析切面,并获取advisors集合)对象
- 源码:
- 首先调用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); }
- 然后调用AnnotationAwareAspectJAutoProxyCreator的initBeanFactoryff
@Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.initBeanFactory(beanFactory); if (this.aspectJAdvisorFactory == null) { this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } // 内部类,它的父类是BeanFactoryAspectJAdvisorsBuilder this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); }
- 调用AbstractAdvisorAutoProxyCreator的initBeanFactory
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); }
- finishBeanFactoryInitialization(beanFactory)
- 创建剩余非懒加载的bean,并存到单例缓存池,如:业务逻辑类,主配置类,切面类
- 解析主配置类(如:aopConfig)时,在resolveBeforeInstantiation中AbstractAutoproxyCreator的postProcessBeforeInstantiation的shouldSkip中,
由ReflectiveAspectJAdvisorFactory#getAdvisors获取advisors(不包含ExposeInvocationInterceptor)
- 源码:
- 由ReflectiveAspectJAdvisorFactory(在上一步已创建对象)调用getAdvisors
```
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
// 先获取切面的通知方法(加了通知注解的方法)
for (Method method : getAdvisorMethods(aspectClass)) {
// 调用以下方法,获取每个通知的增强器,返回类型是InstantiationModelAwarePointcutAdvisorImpl
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
```
```
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 构造函数中会创建advice
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
```
```
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 创建advice对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}
```
- InstantiationModelAwarePointcutAdvisorImpl的instantiateAdvice方法
```
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}
```
- 根据通知方法的注解,分别返回对应的AspectJXXXAdvice对象,@Around/@Before/@After/@Afterreturning/@AfterThrowing
```
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
```
- 解析被代理的业务逻辑类(如:mathCalculator)时,在doCreateBean中AbstractAutoproxyCreator的postProcessAfterInitialization中获取代理对象(advisors中添加ExposeInvocationInterceptor,
并调用AspectJAwareAdvisorAutoProxyCreator#sortAdvisors排序)
- 源码:
- 获取代理对象的入口
```
@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;
}
```
```
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;
}
// 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;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
```
- createProxy
创建代理对象,把之前解析主配置类得到的advisors集合作为参数传入,
在getProxy中,把ProxyCreatorSupport对象本身作为参数,传入到DefaultAopProxyFactory#createAopProxy方法,返回ObjenesisCglibAopProxy对象(ProxyCreatorSupport对象作为参数),初始化ObjenesisCglibAopProxy的父类CglibAopProxy,设置advised的值为(ProxyCreatorSupport类型的对象,其中包含advisors集合)
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);
}
// 依次调用父类AdvisedSupport,ProxyCreatorSupport的构造函数,
// 分别声明advisorChainFactory = new DefaultAdvisorChainFactory(),
// aopProxyFactory = new DefaultAopProxyFactory()
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);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
- DefaultAopProxyFactory的createAopProxy,根据是否实现接口,采用cglib动态代理或JDK动态代理
```
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!NativeDetector.inNativeImage() &&
(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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
```
- 最后返回代理对象
Spring AOP通知集合如何获取以及代理对象的生成
-
结合Spring Ioc容器的加载流程分析,在finishBeanFactoryInitialization这一步解析主配置类的bean,调用过程如下:
- resolveBeforeInstantiation这一步,AbstractAutoProxyCreator的postProcessBeforeInstantiation方法
- AspectJAwareAdvisorAutoProxyCreator#shouldSkip
- AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
- BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors(这里BeanFactoryAspectJAdvisorsBuilder对象实例通过在registerBeanPostProcessors方法中创建)
-
ReflectiveAspectJAdvisorFactory调用相关类的方法
- 如果是切面,由advisorFactory获取当前切面的所有通知advisors,并存储到advisorsCache(map类型,key是beanName,value是advisors)
- 创建BeanFactoryAspectInstanceFactory对象factory
-
ReflectiveAspectJAdvisorFactory#getAdvisors(factory),参数是上一步中创建的factory
- 创建LazySingletonAspectInstanceFactoryDecorator对象(创建MetadataAwareAspectInstanceFactory的装饰器,便于它只被实例化一次!)
- getAdvisorMethods
通过反射得到切面类的通知方法,并循环遍历该集合,集合返回之前排序(按照Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class的顺序)
- 返回InstantiationModelAwarePointcutAdvisorImpl对象,类型是Advisor
- 如果是切面,最后把beanName加到aspectBeanNames(List类型,因为可以定义多个切面)中
- 核心过程见上述的源码
-
解析业务逻辑类,获取它的代理对象,获取过程如下[核心过程见上述的源码]:
- doCreateBea -> initializingBean -> applyBeanPostProcessorsAfterInitialization
- AbstractAutoProxyCreator#postProcessAfterInitialization
-
wrapIfNecessary 返回代理对象
- AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean,从属性aspectBeanNames,advisorsCache中获取,他们赋值的地方在(finishBeanFactoryInitialization中,当beanName是aopConfig时,resolveBeforeInstantiation中解析切面)
- extendAdvisors添加ExposeInvocationInterceptor.ADVISOR到集合的第一个
- 把当前bean存入advisedBeans
- createProxy
创建代理对象,把之前解析主配置类得到的advisors集合作为参数传入,
在getProxy中,把ProxyCreatorSupport对象本身作为参数,传入到DefaultAopProxyFactory#createAopProxy方法,返回ObjenesisCglibAopProxy对象(ProxyCreatorSupport对象作为参数),初始化ObjenesisCglibAopProxy的父类CglibAopProxy,设置advised的值为(ProxyCreatorSupport类型的对象,其中包含advisors集合)
- 创建ProxyFactory对象proxyFactory,依次实例化:AdvisedSupport(创建默认的DefaultAdvisorChainFactory对象),ProxyCreatorSupport(创建默认的DefaultAopProxyFactory对象)
- proxyFactory#getProxy
- createAopProxy(),如果当前bean是接口,则返回JdkDynamicAopProxy对象,否则,返回ObjenesisCglibAopProxy对象
- getProxy调用对应类的代理方法,生成bean的代理对象
Spring AOP拦截器链的生成
- 以Cglib动态代理为例,CglibAopProxy执行拦截器链的生成
-
当调用业务的逻辑方法时,代码会进入CglibAopProxy的内部类DynamicAdvisedInterceptor,intercept方法
- 源码;
@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) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; } // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool... target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); // 获取拦截器链 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. 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); } else { // We need to create a method invocation... // 开始链式的调用 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; } finally { if (target != null && !targetSource.isStatic()) { targetSource.releaseTarget(target); } if (setProxyContext) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
- 调用AdvisedSupport的方法
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable 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; }
- 进入DefaultAdvisorChainFactory,主要是把前面解析得到的AspectJXXXAdvice集合,转换为MethodInterceptor集合
@Override public List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, @Nullable Class<?> targetClass) { // This is somewhat tricky... We have to process introductions first, // but we need to preserve order in the ultimate list. AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); Advisor[] advisors = config.getAdvisors(); List<Object> interceptorList = new ArrayList<>(advisors.length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); Boolean hasIntroductions = null; for (Advisor advisor : advisors) { if (advisor instanceof PointcutAdvisor) { // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); boolean match; if (mm instanceof IntroductionAwareMethodMatcher) { if (hasIntroductions == null) { hasIntroductions = hasMatchingIntroductions(advisors, actualClass); } match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions); } else { match = mm.matches(method, actualClass); } if (match) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); 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; }
- 转换用到了DefaultAdvisorAdapterRegistry,支持3种适配转换器:MethodBeforeAdviceAdapter,AfterReturningAdviceAdapter,ThrowsAdviceAdapter
@Override public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List<MethodInterceptor> interceptors = new ArrayList<>(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[0]); }
- MethodBeforeAdviceAdapter
@Override public boolean supportsAdvice(Advice advice) { return (advice instanceof MethodBeforeAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); return new MethodBeforeAdviceInterceptor(advice); }
- AfterReturningAdviceAdapter
@Override public boolean supportsAdvice(Advice advice) { return (advice instanceof AfterReturningAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice(); return new AfterReturningAdviceInterceptor(advice); }
- ThrowsAdviceAdapter
@Override public boolean supportsAdvice(Advice advice) { return (advice instanceof ThrowsAdvice); } @Override public MethodInterceptor getInterceptor(Advisor advisor) { return new ThrowsAdviceInterceptor(advisor.getAdvice()); }
Spring AOP的调用过程
- MethodInvocation的链式生成过程,通过上一步获取拦截器链之后,调用CglibMethodInvocation的proceed,触发链式调用
-
调用过程运用的软件设计模式是职责链模式
- 调用过程源码:
- new CglibMethodInvocation()
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method, Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) { super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers); // Only use method proxy for public methods not derived from java.lang.Object this.methodProxy = (Modifier.isPublic(method.getModifiers()) && method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) && !AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ? methodProxy : null); }
- 调用父类ReflectiveMethodInvocation的构造函数
protected ReflectiveMethodInvocation( Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) { this.proxy = proxy; this.target = target; this.targetClass = targetClass; this.method = BridgeMethodResolver.findBridgedMethod(method); this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments); this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers; }
- 开始调用CglibMethodInvocation的proceed方法
@Override @Nullable public Object proceed() throws Throwable { try { return super.proceed(); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) || KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) { // Propagate original exception if declared on the target method // (with callers expecting it). Always propagate it for Kotlin code // since checked exceptions do not have to be explicitly declared there. throw ex; } else { // Checked exception thrown in the interceptor but not declared on the // target method signature -> apply an UndeclaredThrowableException, // aligned with standard JDK dynamic proxy behavior. throw new UndeclaredThrowableException(ex); } } }
- 调用父类ReflectiveMethodInvocation的proceed方法,不断地从增强器中获取增强器,在ReflectiveMethodInvocation与子类CglibMethodInvocation来回调用,而且通过在各个MethodInterceptor实现类中实现链式调用
@Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); } 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; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, 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 { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
- 按照调用栈从底向上,依次为ExposeInvocationInterceptor:
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { MethodInvocation oldInvocation = invocation.get(); invocation.set(mi); try { return mi.proceed(); } finally { invocation.set(oldInvocation); } }
- AspectJAroundAdvice(如果有环绕通知)
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); JoinPointMatch jpm = getJoinPointMatch(pmi); return invokeAdviceMethod(pjp, jpm, null, null); }
- MethodBeforeAdviceInterceptor
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); return mi.proceed(); }
- AspectJAfterAdvice
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { invokeAdviceMethod(getJoinPointMatch(), null, null); } }
- AfterReturningAdviceInterceptor
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { Object retVal = mi.proceed(); this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }
- AspectJAfterThrowingAdvice
@Override @Nullable public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } catch (Throwable ex) { if (shouldInvokeOnThrowing(ex)) { invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } }
- 当增强器都遍历完,则调用业务方法
// We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); }
- 最后依次出栈,完成整个链式调用
AOP运用的设计模式
- 职责链模式的出现背景是:把请求的发起者与处理者解耦,也就是说,客户端只管发送请求,至于请求该谁处理由请求链决定
- 状态模式与职责链的不同在于:状态的改变条件,在类中是已经写好的,无法在客户端灵活设置
- AOP拦截器链的执行过程,请求处理者的拦截器链是在切面中定义,可以灵活设置,请求沿着链传递(只是aop约定好了前置、后置、正常返回,异常返回这些切面逻辑)
总结
-
AOP拦截器链的执行,运用的软件设计模式
- 责任链模式
-
拦截器链advisor转换为MethodInterceptor的逻辑
-
实现了MethodInterceptor接口
- AspectJAfterThrowingAdvice
- AspectJAfterAdvice
-
未实现MethodInterceptor接口
- AspectJAfterReturningAdvice
- AspectJMethodBeforeAdvice
-
-
BeanFactoryAspectJAdvisorsBuilder中的advisorsCache在何时赋值?
- BeanFactoryAspectJAdvisorsBuilder的buildAspectJAdvisors方法,同步块双重检查锁定中,先获取advisors,然后put到cache中
待细化
- ReflectiveAspectJAdvisorFactory中的getAdvisorMethods()对切面中定义的@Befre/@Around/@After/@AfterReturning/@AfterThrowing注解标注的方法排序
-
使用
- AspectJ指示器:execution/@args/@annotations......
- @AfterReturning可设置returing()属性
- @AfterThrowing可以设置throwing()属性
- @Around注解以及标注的方法的调用逻辑
- 多切面,多个被拦截方法