WhatAKitty Daily

A Programmer's Daily Record

多个AspectJ对同一个对象操作产生的实际效果以及顺序情况

WhatAKitty   阅读次数loading...

前提

  • Spring 5
  • 基于Java Configuration配置,而非XML配置
  • 对于AspectJ的分析,不对Spring本身的Advisor做分析

概要

如果需要了解多个AscpectJ对同一个对象操作产生的实际效果以及作用顺序,则需要首先了解AOP对象的构建过程,以及如何织入,还有就是织入过程中的顺序逻辑的了解。

所以,这篇文章主要内容如下:

AOP构造者注册

AOP构造者的注册是通过Spring的Import机制实现。在EnableAspectJAutoProxy注解上,存在@Import注解,其内部有实现了ImportBeanDefinitionRegistrar接口的AspectJAutoProxyRegistrar类。

在这里简单介绍下ImportBeanDefinitionRegistrar接口。

ImportBeanDefinitionRegistrar接口常被用于Spring动态bean注册。这个接口会被ConfigurationClassPostProcessor类内的ConfigurationClassParser代理类解析,并通过ConfigurationClassBeanDefinitionReader类的loadBeanDefinitions方法调用所有实现了ImportBeanDefinitionRegistrar接口类的registerBeanDefinitions方法。

以下是ImportBeanDefinitionRegistrar类执行registerBeanDefinitions的过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// 1. 容器上下文注册
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
// 刷新
refresh();
}

// 2. 执行invokeBeanFactoryPostProcessors
public void refresh() throws BeansException, IllegalStateException {
// ...
invokeBeanFactoryPostProcessors(beanFactory);
// ...
}

// 3. 执行PostProcessor代理类的invokeBeanFactoryPostProcessors方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// 4. 循环所有的beanProcessors
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}

// 5. 执行ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry方法
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
processConfigBeanDefinitions(registry);
}

// 6. 实例化ConfigurationClassParser类,并执行解析操作(比如@PropertySources、@ComponentScans、@Import、@ImportSelectors等等注解的解析处理)
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
parser.parse(candidates);

// 7. 加载Bean解析信息
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);

// 8. 从配置类加载Bean解析信息
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}

if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}

loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 加载Import registry的信息
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

9. ImportBeanDefinitionRegistrar执行bean解析
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}

在注册过程中,ImportBeanDefinitionRegistrar类先将AnnotationAwareAspectJAutoProxyCreator注册到了Bean容器内,然后通过EnableAspectJAutoProxy注解,将proxyTargetClassexposeProxy属性注入到 AnnotationAwareAspectJAutoProxyCreator类的bean定义内。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 将AnnotationAwareAspectJAutoProxyCreator注册到Bean容器
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
// 注册属性proxyTargetClass
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
// 注册属性exposeProxy
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}

AOP代理对象的初始化构建

AOP的代理对象是在BeanPostProcesser的处理回调内创建的,AOP的代理创建类实现了BeanPostProcesser的接口,该类名为AnnotationAwareAspectJAutoProxyCreator

本质上来说,是它的父类AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,而这个接口继承了InstantiationAwareBeanPostProcessor接口,同时InstantiationAwareBeanPostProcessor接口继承了BeanPostProcesser接口。

在类初始化完成后,会调用AbstractAutoProxyCreator类的postProcessAfterInitialization方法,在这个方法内,会获取目标对象的所有advice来判断是否需要构建代理类。

1
2
3
4
5
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 需要代理,创建具体的代理类
// ...
}

具体来看一下getAdvicesAndAdvisorsForBean方法,主要是搜索Advisor类的实现和标注有@Aspect注解的类,并且获取@Aspect注解类内的切面点(以下逻辑内容实现在AnnotationAwareAspectJAutoProxyCreator类内,覆盖了父类AbstractAutoProxyCreatorfindCandidateAdvisors方法)。

1
2
3
4
5
6
7
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;

如果没有实现Advisor接口类,则super.findCandidateAdvisors()返回的会是一个空列表。本文也主要探究的是AspectJ相关的具体实现逻辑,所以忽略父类的Advisor搜索逻辑,来具体看一下buildAspectJAdvisors方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// this.aspectBeanNames缓存的是本次容器启动后的切面类名称列表,如果刚启动,则为空
List<String> aspectNames = this.aspectBeanNames;

// 判断是否为null,如果是的话,锁类并且初始化切面类名称
if (aspectNames == null) {
synchronized (this) {
// 再次判断是否为空,确保其他线程在获取锁后不会重复做初始化操作
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 查找所有父类为Object的bean对象
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
// 判断是否需要通过[includePatterns]属性过滤,不过Java配置的AOP貌似不支持这个属性,也可能是没找到在哪里
if (!isEligibleBean(beanName)) {
continue;
}
// 在这里不需要立即实例化类;因为,通过getType方法它会被Spring容器缓存,但是却不会被织入
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 判断获取的类是否为Aspect类
if (this.advisorFactory.isAspect(beanType)) {
// 如果是的话,则将类加入切面类名称列表内
aspectNames.add(beanName);
// 初始化切面元数据
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 判断切面类是否为单例类型
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 通过bean工厂类获取对应切面类的所有Advisor
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 如果bean工厂类为单例,则将Advisors缓存到key为切面类名的advisorsCache内
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 如果bean工厂类不为实例,则缓存缓存到key为切面类名的aspectFactoryCache内
this.aspectFactoryCache.put(beanName, factory);
}
// 将所有的Advisors缓存到advisors列表内
advisors.addAll(classAdvisors);
}
else {
// 每个切面类需要对应有工厂类
if (this.beanFactory.isSingleton(beanName)) {
// 如果工厂类是单例,则抛出异常
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
// 缓存缓存到key为切面类名的aspectFactoryCache内
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}

// 切面类名称列表不为null
// 判断获取到的切面类名称列表是否为空
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
// 从advisorsCache内获取切面类的所有Advisors
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
// 如果cachedAdvisors为空,则从aspectFactoryCache缓存内获取bean工厂,并且通过bean工厂获取所有的Advisors
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;

以上代码基本描述的就是遍历容器内的所有对象,并且判断对象是否是Aspect类型,如果是的话加入到Advisors列表内,并返回。具体判断逻辑如下:

1
2
// 判断是否有@Aspect的注解或者这个类的字段名称存在`ajc$`前缀(如果被AspectJ Compiler编译的类会带有这个前缀)
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));

获取了所有的Advisors之后,需要判断列表是否不为空,即specificInterceptors != DO_NOT_PROXY

如果不为空,则创建具体的代理类。

1
2
3
4
5
6
7
// 将此advisor存入advisedBeans缓存
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 缓存代理类的类型,存入proxyTypes缓存
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;

先看下代理类的具体创建逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {

// 如果bean工厂是ConfigurableListableBeanFactory的实例,则标记exposeTargetClass属性
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}

ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);

// 判断AspectJ有没有设置proxyTargetClass属性(代理类直接继承目标类)
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

// 构建切面
// 对所有的切面(common、advisor、advice)做一次封装,将之全部分装为Advisor类型
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置代理目标类
proxyFactory.setTargetSource(targetSource);
// 子类回调,目前AnnotationAwareAspectJAutoProxyCreator未覆盖该方法,忽略
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}

// 获取代理类
return proxyFactory.getProxy(getProxyClassLoader());
}

接下来就是通过代理工厂来具体创建代理类,Spring中,可以通过两种方式来创建代理类:

  • Jdk动态代理
  • Cglib动态代理

具体使用哪种方式的通过如下条件判断:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 未配置优化且未设置proxyTargetClass为true且有用户自定义的代理接口,则直接使用JDK动态代理
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动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 其他情况使用Cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}

在这里,对JDK动态代理不做具体分析,具体来看ObjenesisCglibAopProxy类内getProxy的获取:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}

try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}

// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);

// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

// 获取回调方法(其中包括最重要的aopInterceptor,用于advices调用链的处理)
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);

// 生成代理class和代理实例
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}

AOP advice的顺序问题

其实在通过AbstractAutoProxyCreator类的findCandidateAdvisors方法获取所有的advice后,会对这些advice做一个排序处理:

1
2
3
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}

Advisors的排序实现是通过AnnotationAwareOrderComparator类来达成的。这个类继承了OrderComparator类,覆盖了findOrdergetPriority方法。

其内部实现的顺序为:Ordered接口 -> 类级别的Order -> 类级别的Prority -> 其他被注解元素的Order -> 其他被注解元素的Prority。

AOP advice的具体调用

Spring AOP的实现并不是将所有的advice硬编码进目标代理类,而是通过织入DynamicAdvisedInterceptor类,在intercept方法内部调用advice调用链来达到拦截的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@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...
// 如果存在调用链,则实例化一个CglibMethodInvocation类,并执行获得返回值
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);
}
}
}

接下来看下CglibMethodInvocationproceed方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//	We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 如果调用链全部执行完毕,则执行被代理对象的原方法
return invokeJoinpoint();
}

// 获得本次的advice
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 {
// 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);
}

拦截器的执行顺序,是根据调用链的顺序来执行的,而调用链的顺序早在之前的sort阶段就已经排列好了;如下的代码主要是获取目标对象和方法对应的拦截器链:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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.
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();

for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
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;
}

举个例子,声明拦截目标类:

1
2
3
4
5
6
7
8
@Component
public class Hello {

public void world() {
System.out.println("hello world");
}

}

定义两个拦截器HelloAop以及HelloAop2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@Aspect
@Component
public class HelloAop {

@Pointcut("execution(* com.whatakitty.learn.Hello.*(..))")
public void world() {
}

@Before("world()")
public void before() {
System.out.println("start hello world");
}

@After("world()")
public void after() {
System.out.println("end hello world");
}

@Around("world()")
public void around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("around 1");
try {
proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("around 1");
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Aspect
@Component
public class HelloAop2 {

@Pointcut("execution(* com.whatakitty.learn.Hello.*(..))")
public void world() {
}

@Before("world()")
public void before() {
System.out.println("start hello world 2");
}

@After("world()")
public void after() {
System.out.println("end hello world 2");
}

@Around("world()")
public void around(ProceedingJoinPoint proceedingJoinPoint) {
System.out.println("around 2");
try {
proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("around 2");
}


}

执行结果如下:

1
2
3
4
5
6
7
8
9
around 1
start hello world
around 2
start hello world 2
hello world
around 2
end hello world 2
around 1
end hello world