SpringAop源码-基于AspectJ注解的方式

官方aop

1.SpringAOP的基本概念

Aspect切面

就是定义切入点、通知等载体.如果使用@AspectJ注解的方式它就是一个类,如果使用Schema-based(springxml)的方式,它就是一个标签.

例如以@AspectJ注解的方式

1
2
3
4
5
6
java复制代码@Aspect
public class PointCutExample {
// 定义一个PointCut切点
@Pointcut("execution(* com.spring.Aop..service.*.*(..))")
public void businessService() {}
}
1
2
3
4
5
6
7
java复制代码@Aspect
public class AdviceExample {
//定义一个advice通知
@Before("com.spring.Aop.aspect.PointCutExample.businessService()")
public void before(JoinPoint joinPoint) {
log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
}

也可以把通知和切点都写到一个Aspect切面里.
以Schema-based xml的方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
xml复制代码 <!--目标对象一个普通bean-->
<bean id="userServiceImpl" class="com.spring.Aop.service.。在上例中目标点就是UserServiceImpl类中的"></bean>

<!--声明一个advice-->
<bean id="logArgsAdvice" class="com.spring.Aop.aspect.LogArgsAdvice"></bean>

<aop:config>
<!--定义切点-->
<aop:pointcut id="logArgsPointCut" expression="execution(* com.spring.Aop..service.*.*(..))"></aop:pointcut>
<!--定义advice通知-->
<aop:aspect ref="logArgsAdvice">
<aop:before method="before" pointcut-ref="logArgsPointCut"></aop:before>
</aop:aspect>
</aop:config>
1
2
3
4
5
6
7
java复制代码//advice通知并没有加注解@AspectJ
public class LogArgsAdvice {

public void before(JoinPoint joinPoint) throws Throwable {
log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
}
}

JoinPoint连接点

叫目标点更好理解.就是需要进行拦截的目标方法,在Aop的理念中很多地方都可以作为连接点,进行添加横切逻辑.但springAop中连接点就单指某个方法。在上例中连接目标点就是UserServiceImpl类中的所有方法。

PointCut切点

定义查找匹配连接点的表达式,可以简单的认为PointCut就是JoinPoint的集合.
代表被表达式匹配上的所有连接点.

advice通知

横切逻辑,前置通知、后置通知等等

注意:

@AspectJ注解使用了AOP的概念.跟AspectJ是没有关系的,只是用了个名字。

2.代码实现基于@AspectJ注解方式

定义连接点JoinPoint,也就是需要代理的目标方法 UserService.java

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
typescript复制代码//UserService接口
public interface UserService {
User createUser(String name,Integer age);
User queryUser();
}
//UserServiceImpl实现类
@Slf4j
public class UserServiceImpl implements UserService {
private static User user = null;

@Override
public User createUser(String name, Integer age) {
user = new User();
user.setName(name);
user.setAge(age);
log.info("UserServiceImpl createUser 方法执行中....");
return user;
}

@Override
public User queryUser() {
log.info("UserServiceImpl queryUser 方法执行中....");
return user;
}
}

定义pointCut切点,就是匹配查找JoinPoint连接点的表达式 UserPointCut.java

1
2
3
4
5
6
7
java复制代码// 定义PointCut
@Aspect
public class UserPointCut {

@Pointcut("execution(* com.spring.Aop..service.*.*(..))")
public void businessService() {}
}

定义Advice通知,也就是需要增强的横切逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
less复制代码@Slf4j
@Aspect
public class UserAdvice {

@Before("com.spring.Aop.aspect.UserPointCut.businessService()")
public void before(JoinPoint joinPoint) {
log.info("准备执行方法:{},参数列表:{}",joinPoint, Arrays.asList(joinPoint.getArgs()));
}

@AfterReturning(pointcut = "com.spring.Aop.aspect.UserPointCut.businessService()",returning="returnValue")
public void afterReturning(JoinPoint joinPoint,Object returnValue){
log.info("{}方法执行返回:{}",joinPoint,returnValue);
}

application xml配置文件 springAop-2.0aspectJ.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
xml复制代码<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!--普通bean-->
<bean id="userService" class="com.spring.Aop.service.UserServiceImpl"></bean>

<!--定义advice通知-->
<bean id="userAdvice" class="com.spring.Aop.aspect.UserAdvice"></bean>

<!--开启@AspectJ配置-->
<aop:aspectj-autoproxy/>

</beans>

测试代码

1
2
3
4
ini复制代码ClassPathXmlApplicationContext applicationContext =  new ClassPathXmlApplicationContext("classpath:springAop-2.0aspectJ.xml");
UserService userService = applicationContext.getBean(UserService.class);
userService.createUser("Jom",12);
userService.queryUser();

运行结果:

image.png

3.SpringAop的底层原理

代理模式是springAop的实现原理,但是具体是怎么的呢?如果让我们自己是实现springAop的功能,会怎么做?

3.1动态代理的原理

①.调用Proxy.newProxyInstance生成代理对象.

②.继承InvocationHandler接口,实现Invoke方法,可以在invoke方法添加各种通知横切逻辑,同时调用目标对象的方法.

③.JDK自动生成的代理对象会继承目标对象的接口,并实现目标对象需要代理的方法.方法里再调用②中的invoke方法,而invoke方法中又调用了目标对象的方法,这样就实现了代理的功能.

3.2自己实现aop的思路

①.首先要一个处理aop的工具类

②.找到需要代理的目标类

③.工具类里实现Invoke方法,将寻找到的advice和目标方法调用添加进去.

④.生成代理类对象.因为依赖Jdk动态代理,实现invoke方法将目标对象传入进去即可.

问题:

1.IOC容器如何区分普通类和代理类?— 通过接口BeanPostProcessor区分的

2.因PointCut切点是匹配表达式,就有可能匹配到很多不同的service方法,会生成一个代理对象包含所有的方法代理?还是生成多个代理对象? —对于单个被代理的目标对象来说只会生成任意一个代理对象,但在实际执行invoke里会循环执行全部匹配上的advice执行链.

4.源码实现

4.1.查找到处理aop的工具类

在这里是AnnotationAwareAspectJAutoProxyCreator,那怎么找到该类呢?

1.找到开头标签aop对应的命名空间
image.png

2.全局搜索命名空间:www.springframework.org/schema/aop 注意http后需加一个 “\”,在spring.handlers找到对应的Handler
image.png
3.再根据Handler找到对应的Parser,这里是AspectJAutoProxyBeanDefinitionParser
image.png
4.AspectJAutoProxyBeanDefinitionParser代码如下,parse()方法里会注册AnnotationAwareAspectJAutoProxyCreator类.

1
2
3
4
5
6
7
8
9
less复制代码//解析方法
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
//注册类到Ioc容器
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
extendBeanDefinition(element, parserContext);
return null;
}

进入registerAspectJAnnotationAutoProxyCreatorIfNecessary方法

1
2
3
4
5
6
7
8
9
10
11
scss复制代码public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//将一个类定义注册到IOC容器,并返回对象BeanDefinition
//这个就是AnnotationAwareAspectJAutoProxyCreator.class
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//处理proxy-target-class与expose-proxy属性,将beanDefinition对应的属性设置为true/false
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//注册组件
registerComponentIfNecessary(beanDefinition, parserContext);
}

image.png
最终注册bean的key就是这个,下面会进行debug验证.

4.2 Aop处理类Creator何时被加载

那么springIOC容器是知道加载这个类呢?在何时加载的呢?

此处涉及到IOC知识,不详细展开。spring在读取xml配置文件时,会解析xml中的配置,也包括xml文件中的声明部分.
先看下IOC的启动流程,AbstractApplicationContext的refresh()方法.

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
scss复制代码@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

// Prepare this context for refreshing.
prepareRefresh();

// a.此处加载AnnotationAwareAspectJAutoProxyCreator的bean定义
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// b.注册和创建AnnotationAwareAspectJAutoProxyCreator对象
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// c.注册创建普通的bean对象
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}

先看a处的代码,进入到obtainFreshBeanFactory()方法,发现里面又调用了refreshBeanFactory()方法.
refreshBeanFactory在AbstractRefreshableApplicationContext中代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
scss复制代码@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//对IOC容器进行定制化,如设置是否允许循环引用、是否允许bean定义覆盖重写等
customizeBeanFactory(beanFactory);
//加载Bean定义
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

loadBeanDefinitions方法最终会调用执行上面的AspectJAutoProxyBeanDefinitionParser的parse方法.loadBeanDefinitions执行后debug如下

image.png
可以看到BeanDefinitionMap里除了我们自己定义的bean之外,还多了一个org.springframework.aop.config.internalAutoProxyCreator。

4.2.创建Aop处理类Creator的对象

先看看Creator类的继承关系图如下
image.png
可以看到该类继承实现了BeanPostProcessor接口.这个接口大家应该很熟悉,就是spring设计的扩展功能实现.

另外关于动态代理的执行时机问题,是需要目标对象被创建初始化后,才能进行动态处理操作.不然目标对象都没有,代理谁呢?不符合逻辑.

从IOC的启动流程来说,有了Bean定义同时又实现了BeanPostProcessor接口.故在registerBeanPostProcessors(beanFactory)时会将该Creator类注册到容器里,参看4.2 b处的代码.注意这里注册就会创建Creator类对象了,创建的时机在普通的bean之前,这点尤其重要.

registerBeanPostProcessors源码如下:

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
scss复制代码public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//查找实现了BeanPostProcessor的类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 存放实现PriorityOrdered的PostProcessors
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 存放实现MergedBeanDefinitionPostProcessor的PostProcessors
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 存放实现Ordered的PostProcessors
List<String> orderedPostProcessorNames = new ArrayList<>();
// 存放以外情况的PostProcessors
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// 此时PostProcessors对象还没有被创建,所以存放beanName
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// Next, register the BeanPostProcessors that implement Ordered.
// 这里注册实现了Ordered的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
// 重点:创建BeanPostProcessors对象 最终会调用执行doCreateBean方法.
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
//将创建好的BeanPostProcessors对象 存放到beanPostProcessors列表中.
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

// Now, register all regular BeanPostProcessors.
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);

// Finally, re-register all internal BeanPostProcessors.
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));
}

到这里AnnotationAwareAspectJAutoProxyCreator类的对象已经创建好了,提前创建此种类型对象spring是通过其继承实现了BeanPostProcessor识别的.

4.4 创建普通Bean对象,如何变成代理对象的

创建普通Bean对象也就是需要代理的目标对象,在refresh()方法的finishBeanFactoryInitialization(beanFactory)里面,参看4.2的c处标记。
通过该方法一直点下去,最终会调用到AbstractAutowireCapableBeanFactory.doCreateBean()真正创建对象的地方.如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
scss复制代码//省略。。。。
if (instanceWrapper == null) {
// 创建对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//省略。。。。
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充Bean,设置属性啥的
populateBean(beanName, mbd, instanceWrapper);
// 初始化Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
//省略。。。。

进入initializeBean方法

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
ini复制代码protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 1. 执行每一个 BeanPostProcessor 的 postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
// 调用 bean 配置中的 init-method="xxx"
invokeInitMethods(beanName, wrappedBean, mbd);
}
....
if (mbd == null || !mbd.isSynthetic()) {
// 2.重点关注 执行每一个 BeanPostProcessor 的 postProcessAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

applyBeanPostProcessorsAfterInitialization会循环调用IOC容器中所有的BeanPostProcessor,上面创建的Creator对象的postProcessAfterInitialization在这里会被执行,执行后目标对象就被包装成代理对象了。
至此IOC是如何加载代理对象和普通目标对象就清晰了。接下来就是SpringAop主要内容了。

4.5 创建代理对象

被调用的postProcessAfterInitialization方法在AnnotationAwareAspectJAutoProxyCreator的父接口AbstractAutoProxyCreator中,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
less复制代码@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
//此处的参数bean和beanName就是目标对象,此时目标对象已经被创建出来了.
if (bean != null) {
//从缓存中获取bean的名字key,如果是FactoryBean类型的key前面加&标识,以外的正常返回
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//执行处理,处理完如果是aop类型就返回代理后的对象,给到ioc容器
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

wrapIfNecessary方法的详细处理

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
kotlin复制代码protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//beanName不可空 && 已经处理过的直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//advisedBeans中包含是类型为Advice、Pointcut、Advisor、AopInfrastructureBean都跳过直接返回.
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;
}
// 4.5.1 寻找匹配该目标Bean的横切逻辑方法(advice和advisor之类的)
// 在我们上面的例子就是UserAdvice里的before和afterReturning方法
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//4.5.2生成真正的代理对象proxy,即利用JDK动态代理或cglib生成的$proxy0@xxx对象
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;
}

这步处理结束后、就返回想要的代理对象了.

4.5.1 寻找匹配目标Bean的通知方法(advice和advisor)

getAdvicesAndAdvisorsForBean是抽象方法,具体的实现有2个子类分别是AbstractAdvisorAutoProxyCreator和BeanNameAutoProxyCreator。
而AbstractAdvisorAutoProxyCreator是上面注册的AnnotationAwareAspectJAutoProxyCreator的父类,故找AbstractAdvisorAutoProxyCreator中相应的方法.

1
2
3
less复制代码@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,
@Nullable TargetSource customTargetSource) throws BeansException;

image.png
AbstractAdvisorAutoProxyCreator中getAdvicesAndAdvisorsForBean()

1
2
3
4
5
6
7
8
9
less复制代码protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//查找合适的advisor(继承和注解advisor的类)
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
1
2
3
4
5
6
7
8
9
10
11
scss复制代码protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//先找到容器中全部的advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//再匹配beanName对应的advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
4.5.1.1 查找全部的advisor

findCandidateAdvisors()方法,上面的处理是在AbstractAdvisorAutoProxyCreator中,而findCandidateAdvisors方法在其类中有实现,且在子类中也有实现,此处应该去AnnotationAwareAspectJAutoProxyCreator中的实现,优先调用自己的方法

1
2
3
4
5
6
7
8
9
10
kotlin复制代码protected List<Advisor> findCandidateAdvisors() {
// 找到所有继承了Advisor.class的子类
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
//寻找注解的advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}

经过处理后的advisors里面封装了pointCut和advice信息

4.5.1.2 匹配目标beanName对应的advisor

findAdvisorsThatCanApply()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
scss复制代码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;
}
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}

4.5.2 生成具体的代理对象

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

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
scss复制代码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);
// 判断proxy-target-class="true"
if (proxyFactory.isProxyTargetClass()) {
if (Proxy.isProxyClass(beanClass)) {
for (Class<?> ifc : beanClass.getInterfaces()) {
proxyFactory.addInterface(ifc);
}
}
}
else {
// No proxyTargetClass flag enforced, let's apply our default checks...
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);
}

可以看到proxyFactory对象封装了advisors和目标对象的信息.
proxyFactory.getProxy()

1
2
3
less复制代码public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
1
2
3
4
5
6
kotlin复制代码protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}

根据配置先创建AopProxy对象,再根据AopProxy创建具体的proxy对象.是用JDK动态代理还是Cglib方式.
DefaultAopProxyFactory类createAopProxy()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
arduino复制代码@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//此处的config参数就是proxyFactory对象
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
...
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

我们只看JdkDynamicAopProxy方法在JdkDynamicAopProxy类中

1
2
3
4
5
6
7
8
9
10
11
arduino复制代码public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
//如果不存在Advisor或者目标对象为空的话 抛出异常
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
this.advised = config;
//获取advised里代理对象所继承的所有接口
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//判断标记继承的接口是否有实现equals和hashCode方法
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}

创建具体的代理对象

1
2
3
4
5
6
7
less复制代码@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}

至此代理对象就创建完成了.

4.6 执行调用Aop对象

此处只看JdkDynamicAopProxy JDK动态代理的方式
JDK动态代理的原理,生成的代理对象的方法内部会委托给InvocationHandler.invoke()方法。而invoke方法就会包含各个增强方法(通知),再调用原对象的方法。
看一下JdkDynamicAopProxy的源码实现了InvocationHandler接口

1
kotlin复制代码final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {

重点invoke()

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
kotlin复制代码public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
//method.getDeclaringClass获取Method对应的目标类,method.getClass获得是Method类
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
//Advised接口或者其父接口中定义的方法,直接反射调用,不应用通知
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;

if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//获取目标对象的类
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);

// 获取目标方法的拦截器链.程序上我们可以定义多个Aop切面,而某个目标方法就有可能被多个Aop匹配上,故需要循环执行每个匹配的aop通知.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
//拦截器链为空的,则直接调用目标对象方法
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 创建MethodInvocation
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
retVal = invocation.proceed();
}

//最终方法执行的返回结果
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

ReflectiveMethodInvocation的proceed()

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
kotlin复制代码public Object proceed() throws Throwable {
// 如果执行Interceptor完了,则执行joinPoint.注意currentInterceptorIndex初始值为-1
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 执行Interceptor,根据currentInterceptorIndex逐个获取Interceptor
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.
//执行当前IntercetporAdvice的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

为什么@Before、@After的Advice的invoke可以实现前置、后置的通知效果?
MethodBeforeAdviceInterceptor的invoke()

1
2
3
4
5
scss复制代码public Object invoke(MethodInvocation mi) throws Throwable {
//先执行before方法,执行完后再回调ReflectiveMethodInvocation.proceed()
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}

AfterReturningAdviceInterceptor的invoke()

1
2
3
4
5
6
7
java复制代码public Object invoke(MethodInvocation mi) throws Throwable {
//先回调ReflectiveMethodInvocation.proceed(),因为调用joinPoint在这里
Object retVal = mi.proceed();
//再执行afterReturning
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}

结束。

5.总结

Aop首先需要理解基础的概念,有哪些具体是什么用处,怎么使用的。

其次理解动态代理的原理,这是理解aop的基础。

最后具体的aop实现步骤,先创建代理对象 -> 创建目标对象时 -> 判断是否有匹配上的代理对象 ->找到所有的advice和pointCut -> 再找到和目标对象匹配的advice和pointCut -> 生成实际的代理对象 -> 程序调用 -> 代理对象里会调用invoke方法 -> 执行具体的横切逻辑通知 -> 执行调用目标对象.

另仅个人学习记录,有理解不到位的情况…

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%