Spring学习笔记
- 源码阅读篇
- Spring AOP源码分析
- Spring AOP核心类解析
- Spring AOP基础解析类
- AOP联盟定义的接口
- Spring AOP中定义的类
- Advisor系列(重点)
- Pointcut系列(重点)
- MethodMatcher系列(重点)
- Advised系列
- ProxyConfig系列
- TargetSource系列
- AopProxy系列(重点)
- AopProxyFactory系列
- AdvisorChainFactory系列
- AdvisorAdapterRegistry系列
- AutoProxyUtils系列
- Advice实现系列(重点)
- AbstractAspectJAdvice系列(重点)
- AdvisorAdapter系列(重点)
- AspectJAdvisorFactory系列
- BeanFactoryAspectJAdvisorsBuilder系列
- AspectInstanceFactory系列
- ProxyMethodInvocation系列
- ClassFilter系列(重点)
- 查找BeanDefinitionParser流程分析
- 执行BeanDefinitionParser流程分析
- 产生AOP代理流程分析
- AOP代理对象执行流程
- 事务流程源码分析
源码阅读篇
Spring AOP源码分析
Spring AOP核心类解析
Spring AOP基础解析类
类名 | 作用概述 |
---|---|
AopNamespaceHandler | AOP命名空间解析类。我们在用AOP的时候,会在Spring配置文件的beans标签中引入:xmlns:aop。 |
AspectJAutoProxyBeanDefinitionParser | 解析<aop:aspectj-autoproxy />标签的类。在AopNamespaceHandler中创建的类。 |
ConfigBeanDefinitionParser | 解析<aop:config /> 标签的类。同样也是在AopNamespaceHandler中创建的类。 |
AopNamespaceUtils | AOP命名空间解析工具类,在上面两个中被引用。 |
AopConfigUtils | AOP配置工具类。主要是向Spring容器中注入可以生成Advisor和创建代理对象的bean。 |
AOP联盟定义的接口
接口名 | 作用概述 |
---|---|
Advice | AOP联盟中的一个标识接口,通知和Interceptor顶级类。 我们说的各种通知类型都要实现这个接口。 |
Interceptor | AOP联盟中进行方法拦截的一个标识接口,是Advice的子类。 |
MethodInterceptor | 方法拦截器,是Interceptor的一个重要子接口。 主要方法:invoke;入参为:MethodInvocation。 |
ConstructorInterceptor | 构造方法拦截器,是Interceptor的另一个重要的子接口。 在AOP联盟中是可以对构造方法进行拦截的,这样的场景我们应该很少用到。 主要方法为,construct;入参为ConstructorInvocation。 |
Joinpoint | AOP联盟中的连接点接口。 主要的方法是:proceed()执行下一个拦截器。getThis()获取目标对象。 |
Invocation | AOP拦截的执行接口,是Joinpoint的子接口。 主要方法:getArguments()获取参数。 |
MethodInvocation | Invocation的一个重要子接口,真正执行AOP方法的拦截。 主要方法:getMethod()获取目标方法。 |
ConstructorInvocation | Invocation的另一个重要子接口,执行构造方法的拦截。 主要方法:getConstructor()返回构造方法。 |
Spring AOP中定义的类
Advisor系列(重点)
类名 | 作用概述 |
---|---|
Advisor | SpringAOP中的核心类,组合了Advice。 |
PointcutAdvisor | SpringAOP中Advisor的重要子接口。 组合了切点Pointcut和Advice。 |
InstantiationModelAwarePointcutAdvisorImpl | PointcutAdvisor的一个重要实现子类。 |
DefaultPointcutAdvisor | PointcutAdvisor的另一个重要实现子类。 可以将Advice包装为Advisor。 在SpringAOP中是以Advisor为主线,向Advice靠拢。 |
Pointcut系列(重点)
类名 | 作用概述 |
---|---|
Pointcut | SpringAOP中切点的顶级抽象类。 |
TruePointcut | Pointcut的一个重要实现类。在DefaultPointcutAdvisor中使用的是TruePointcut。 在进行切点匹配的时候永远返回true。 |
AspectJExpressionPointcut | Pointcut的一个重要实现类,AspectJ语法切点类。 同时实现了MethodMatcher,AspectJ语法切点的匹配在这个类中完成。 |
AnnotationMatchingPointcut | Pointcut的一个重要实现类,注解语法的切点类。 |
JdkRegexpMethodPointcut | Pointcut的一个重要实现类,正则语法的切点类。 |
MethodMatcher系列(重点)
类名 | 作用概述 |
---|---|
MethodMatcher | 切点匹配连接点的地方:即类中的某个方法和我们定义的切点表达式是否匹配、能不能被AOP拦截。 |
TrueMethodMatcher | 用于返回true。 |
AnnotationMethodMatcher | 带有注解的方法的匹配器。 |
Advised系列
类名 | 作用概述 |
---|---|
Advised | SpringAOP中的又一个核心接口。它组合了Advisor和TargetSource即目标对象 |
AdvisedSupport | Advised的一个实现类,SpringAOP中的一个核心类。继承了ProxyConfig实现了Advised。 |
ProxyCreatorSupport | AdvisedSupport的子类。引用了AopProxyFactory用来创建代理对象。 |
ProxyFactory | ProxyCreatorSupport的子类,用来创建代理对象。在SpringAOP中用的最多。 |
ProxyFactoryBean | ProxyCreatorSupport的子类,用来创建代理对象。它实现了BeanFactoryAware、FactoryBean接口。 |
AspectJProxyFactory | ProxyCreatorSupport的子类,用来创建代理对象。使用AspectJ语法。 |
ProxyConfig系列
类名 | 作用概述 |
---|---|
ProxyConfig | SpringAOP中的一个核心类。在Advised中定义了一系列的配置接口,例如:是否暴露对象、是否强制使用CGlib等。ProxyConfig是对这些接口的实现,但是ProxyConfig却不是Advised的实现类。 |
ProxyProcessorSupport | ProxyConfig的子类。 |
AbstractAutoProxyCreator | ProxyProcessorSupport的重要子类,SpringAOP中的核心类。实现了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware接口。 自动创建代理对象的类。我们在使用AOP的时候基本上都是用的这个类来进行Bean的拦截,创建代理对象。 |
AbstractAdvisorAutoProxyCreator | AbstractAutoProxyCreator的子类,SpringAOP中的核心类,用来创建Advisor和代理对象。 |
AspectJAwareAdvisorAutoProxyCreator | AbstractAdvisorAutoProxyCreator的子类,使用AspectJ语法创建Advisor和代理对象。 |
AnnotationAwareAspectJAutoProxyCreator | AspectJAwareAdvisorAutoProxyCreator的子类。使用AspectJ语法创建Advisor和代理对象的类。<aop:aspectj-autoproxy />标签默认注入到SpringAOP中的BeanDefinition。 |
InfrastructureAdvisorAutoProxyCreator | AbstractAdvisorAutoProxyCreator的子类,SpringAOP中的核心类,基础建设类,Spring事务默认的创建代理对象的类。 |
TargetSource系列
类名 | 作用概述 |
---|---|
TargetSource | 持有目标对象的接口。 |
SingletonTargetSource | TargetSource的子类,适用于单例目标对象。 |
HotSwappableTargetSource | TargetSource的子类,支持热交换的目标对象。 |
AbstractRefreshableTargetSource | TargetSource的子类,支持可刷新的热部署的目标对象。 |
AbstractBeanFactoryBasedTargetSource | TargetSource的子类,实现了BeanFactoryAware接口。 |
SimpleBeanTargetSource | AbstractBeanFactoryBasedTargetSource的子类,从BeanFactory中获取单例Bean。 |
LazyInitTargetSource | AbstractBeanFactoryBasedTargetSource的子类,从BeanFactory中获取单例Bean。支持延迟初始化。 |
AbstractPrototypeBasedTargetSource | AbstractBeanFactoryBasedTargetSource的子类,对Prototype类型的Bean的支持。 |
ThreadLocalTargetSource | AbstractPrototypeBasedTargetSource的子类,和线程上下文相结合的类。 |
PrototypeTargetSource | AbstractPrototypeBasedTargetSource的子类,从BeanFacory中获取Prototype 类型的Bean。 |
AopProxy系列(重点)
类名 | 作用概述 |
---|---|
AopProxy | 定义生成AOP代理对象的类的接口规范。 |
JdkDynamicAopProxy | AopProxy的实现类,使用JDK的方式创建代理对象。它持有Advised对象,实现了AopProxy接口和InvocationHandler接口。 |
CglibAopProxy | AopProxy的实现类,使用Cglib的方法创建代理对象。它持有 Advised对象。 |
ObjenesisCglibAopProxy | CglibAopProxy的子类,使用Cglib的方式创建代理对象。它持有Advised对象。 |
AopProxyFactory系列
类名 | 作用概述 |
---|---|
AopProxyFactory | 创建AOP代理对象的工厂类的接口,择使用JDK还是Cglib的方式来创建代理对象。 |
DefaultAopProxyFactory | AopProxyFactory的子类,也是SpringAOP中唯一默认的实现类。 |
AdvisorChainFactory系列
类名 | 作用概述 |
---|---|
AdvisorChainFactory | 获取Advisor链的接口。 |
DefaultAdvisorChainFactory | AdvisorChainFactory的实现类。也是SpringAOP中唯一默认的 实现类。 |
AdvisorAdapterRegistry系列
类名 | 作用概述 |
---|---|
AdvisorAdapterRegistry | Advisor适配注册器类接口,用来将Advice适配为Advisor。 将Advisor适配为MethodInterceptor。 |
DefaultAdvisorAdapterRegistry | AdvisorAdapterRegistry的实现类。也是SpringAOP中唯一默认的实现类。持有:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter实例。 |
AutoProxyUtils系列
类名 | 作用概述 |
---|---|
AutoProxyUtils | SpringAOP自动创建代理对象的工具类。 |
Advice实现系列(重点)
- AspectJ有五种通知类型,其中三种是直接可以强转成MethodInterceptor接口。
类名 | 作用概述 |
---|---|
BeforeAdvice | 前置通知接口,直接继承了Advice接口。 |
MethodBeforeAdvice | BeforeAdvice的子接口,定义了方法before,执行前置通知。 |
MethodBeforeAdviceInterceptor | MethodBefore前置通知Interceptor,实现了MethodInterceptor接口,持有MethodBeforeAdvice对象。 |
AfterAdvice | 后置通知接口,直接继承了Advice接口。 |
ThrowsAdvice | 后置异常通知接口,直接继承了AfterAdvice接口。 |
AfterReturningAdvice | 后置返回通知接口,直接继承了AfterAdvice接口。 |
AfterReturningAdviceInterceptor | 后置返回通知Interceptor,实现了MethodInterceptor和 AfterAdvice接口,持有AfterReturningAdvice实例 |
ThrowsAdviceInterceptor | 后置异常通知Interceptor,实现了MethodInterceptor和 AfterAdvice接口,要求方法名为:afterThrowing |
AbstractAspectJAdvice系列(重点)
类名 | 作用概述 |
---|---|
AbstractAspectJAdvice | 使用AspectJ注解的通知类型顶级父类。 |
AspectJMethodBeforeAdvice | 使用AspectJ Before注解的前置通知类型。 实现了MethodBeforeAdvice,继承了AbstractAspectJAdvice。 |
AspectJAfterAdvice | 使用AspectJ After注解的后置通知类型。 实现了 MethodInterceptor、AfterAdvice接口,继承了 AbstractAspectJAdvice。 |
AspectJAfterReturningAdvice | 使用AspectJ AfterReturning注解的后置通知类型。 实现了 AfterReturningAdvice、AfterAdvice接口,继承了 AbstractAspectJAdvice。 |
AspectJAroundAdvice | 使用AspectJ Around注解的后置通知类型。 实现了 MethodInterceptor接口,继承了AbstractAspectJAdvice。 |
AspectJAfterThrowingAdvice | 使用AspectJ Around注解的后置通知类型。 实现了 MethodInterceptor、AfterAdvice接口,继承了AbstractAspectJAdvice。 |
AdvisorAdapter系列(重点)
类名 | 作用概述 |
---|---|
AdvisorAdapter | Advisor适配器,判断此接口的是不是能支持对应的Advice。 五种通知类型,只有三种通知类型适配器。这里可以想一下为什么只有三种。 |
MethodBeforeAdviceAdapter | 前置通知的适配器,支持前置通知类。 有一个getInterceptor方法:将 Advisor适配为MethodInterceptor。 Advisor持有Advice类型的实例, 获取MethodBeforeAdvice,将MethodBeforeAdvice适配为 MethodBeforeAdviceInterceptor。AOP的拦截过程通过 MethodInterceptor来完成。 |
AfterReturningAdviceAdapter | 后置返回通知的适配器,支持后置返回通知类。 有一个getInterceptor 方法:将Advisor适配为MethodInterceptor。 Advisor持有Advice类型的实例,获取AfterReturningAdvice,将AfterReturningAdvice适配为 AfterReturningAdviceInterceptor。AOP的拦截过程通过 MethodInterceptor来完成。 |
ThrowsAdviceAdapter | 后置异常通知的适配器,支持后置异常通知类。 有一个getInterceptor 方法:将Advisor适配为MethodInterceptor。 Advisor持有Advice类型的实例,获取ThrowsAdvice,将ThrowsAdvice适配为 ThrowsAdviceInterceptor。AOP的拦截过程通过MethodInterceptor来完成。 |
AspectJAdvisorFactory系列
类名 | 作用概述 |
---|---|
AspectJAdvisorFactory | 使用AspectJ注解生成Advisor工厂类 |
AbstractAspectJAdvisorFactory | AspectJAdvisorFactory的子类,使用AspectJ注解生成Advisor的工 厂类。 |
ReflectiveAspectJAdvisorFactory | AbstractAspectJAdvisorFactory的子类,使用AspectJ注解生成 Advisor的具体实现类。 |
AspectMetadata | 使用AspectJ Aspect注解的切面元数据类。 |
BeanFactoryAspectJAdvisorsBuilder系列
类名 | 作用概述 |
---|---|
BeanFactoryAspectJAdvisorsBuilder | 工具类,负责构建Advisor、Advice,是SpringAOP核心类。 |
AspectInstanceFactory系列
类名 | 作用概述 |
---|---|
AspectInstanceFactory | Aspect实例工厂类接口 |
MetadataAwareAspectInstanceFactory | AspectInstanceFactory的子接口,含有Aspect注解元数据 Aspect切面实例工厂类。 |
BeanFactoryAspectInstanceFactory | MetadataAwareAspectInstanceFactory的实现类,持有BeanFactory实例。从 BeanFactory中获取Aspect实例。 |
PrototypeAspectInstanceFactory | BeanFactoryAspectInstanceFactory的子类,获取Prototype类型的Aspect实例。 |
SimpleMetadataAwareAspectInstanceFactory | MetadataAwareAspectInstanceFactory的实现类,在AspectJProxyFactory中有使用。 |
SingletonMetadataAwareAspectInstanceFactory | MetadataAwareAspectInstanceFactory的实现类,继承了 SimpleAspectInstanceFactory。 单例Aspect实例类,在AspectJProxyFactory中有使 用。 |
SimpleBeanFactoryAwareAspectInstanceFactory | AspectInstanceFactory的实现类,同时实现了BeanFactoryAware接口。和aop:config配合使用的类。 |
ProxyMethodInvocation系列
类名 | 作用概述 |
---|---|
ProxyMethodInvocation | 含有代理对象,MethodInvocation的子接口。 |
ReflectiveMethodInvocation | ProxyMethodInvocation的实现类,AOP拦截的执行入口类。 |
CglibMethodInvocation | ReflectiveMethodInvocation的子类,对Cglib反射调用目标方法进行了一点改进。 |
ClassFilter系列(重点)
查找BeanDefinitionParser流程分析
- 根据自定义标签,找到对应的BeanDefinitionParser,比如aop:config标签,就对应着ConfigBeanDefinitionParser。
- 阅读经验分享:根据自定义标签名称冒号前面的值去直接找NamespaceHandler,然后再根据自定义标签名称冒号后面的值去找BeanDefinitionParser。
找入口
- DefaultBeanDefinitionDocumentReader#parseBeanDefinitions方法的第16行或者23行:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 加载的Document对象是否使用了Spring默认的XML命名空间(beans命名空间)
if (delegate.isDefaultNamespace(root)) {
// 获取Document对象根元素的所有子节点(bean标签、import标签、alias标签和其他自定义标签context、aop等)
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
// bean标签、import标签、alias标签,则使用默认解析规则
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
//像context标签、aop标签、tx标签,则使用用户自定义的解析规则解析元素节点
delegate.parseCustomElement(ele);
}
}
}
}
else {
// 如果不是默认的命名空间,则使用用户自定义的解析规则解析元素节点
delegate.parseCustomElement(root);
}
}
流程图
流程解析
- BeanDefinitionParserDelegate#parseCustomElement
@Nullable
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 获取命名空间URI(就是获取beans标签的xmlns:aop或者xmlns:context属性的值)
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 根据不同的命名空间URI,去匹配不同的NamespaceHandler(一个命名空间对应一个NamespaceHandler)
// 此处会调用DefaultNamespaceHandlerResolver类的resolve方法
// 两步操作:查找NamespaceHandler 、调用NamespaceHandler的init方法进行初始化(针对不同自定义标签注册相应的BeanDefinitionParser)
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 调用匹配到的NamespaceHandler的解析方法
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
- DefaultNamespaceHandlerResolver#resolve
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// 读取spring所有工程的META-INF/spring.handlers文件,获取namespaceUri和NamespaceHandler的映射关系
Map<String, Object> handlerMappings = getHandlerMappings();
// 获取 指定namespaceUri对应的namespaceHandler
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
// META-INF/spring.handlers文件中存储的value都是String类型的类名
String className = (String) handlerOrClassName;
try {
// 根据类名通过反射获取到NamespaceHandler的Class类对象
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 实例化NamespaceHandler
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用NamespaceHandler类的init方法,初始化一些专⻔处理指定标签的BeanDefinitionParsers类
namespaceHandler.init();
// 将namespaceUri对应的String类型的类名,替换为NamespaceHandler对象,下一次再获取的话,就不会重复创建实例
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
// ...catch省略
}
}
- AopNamespaceHandler#init
@Override
public void init() {
// In 2.0 XSD as well as in 2.1 XSD.
// <aop:config></aop:config>对应的BeanDefinitionParser
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// Only in 2.0 XSD: moved to context namespace as of 2.1
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
- 至此,找到了解析<aop:config></aop:config>对应的BeanDefinitionParser
执行BeanDefinitionParser流程分析
解析aop:config标签,最终解析10个类对应的BeanDefinition
- 产生代理对象的类对应的BeanDefinition(一种):
- AspectJAwareAdvisorAutoProxyCreator
- 通知BeanDefinition(五种):
- AspectJMethodBeforeAdvice
- AspectJAfterAdvice
- AspectJAfterReturningAdvice
- AspectJAfterThrowingAdvice
- AspectJAroundAdvice
- 通知器BeanDefinition(两种):
- DefaultBeanFactoryPointcutAdvisor
- AspectJPointcutAdvisor
- 切入点BeanDefinition(一种):
- AspectJExpressionPointcut
- 用于产生自定义增强类实例的类对应的BeanDefinition:实例工厂去产生自定义功能对应的类的实例
- SimpleBeanFactoryAwareAspectInstanceFactory----增强类的实例
- 用于调用自定义增强类方法对应的BeanDefinition:使用一个封装增强方法的BeanDefinition去封装Method方法
- MethodLocatingFactoryBean—Method对象
找入口
- NamespaceHandlerSupport类的
parse
方法的第6行代码:
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// NamespaceHandler里面初始化了大量的BeanDefinitionParser来分别处理不同的自定义标签
// 从指定的NamespaceHandler中,匹配到指定的BeanDefinitionParser
BeanDefinitionParser parser = findParserForElement(element, parserContext);
// 调用指定自定义标签的解析器,完成具体解析工作
return (parser != null ? parser.parse(element, parserContext) : null);
}
流程图
流程解析
- ConfigBeanDefinitionParser#parse
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
CompositeComponentDefinition compositeDef =
new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
// 获取产生代理对象的代理对象创建器
// AspectJAwareAdvisorAutoProxyCreator
configureAutoProxyCreator(parserContext, element);
List<Element> childElts = DomUtils.getChildElements(element);
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt);
if (POINTCUT.equals(localName)) {
// AspectJExpressionPointcut
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
// DefaultBeanFactoryPointcutAdvisor
// AspectJPointcutAdvisor
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
// AspectJExpressionPointcut
// MethodLocatingFactoryBean
// SimpleBeanFactoryAwareAspectInstanceFactory
// AspectJPointcutAdvisor
// AspectJMethodBeforeAdvice
// AspectJAfterAdvice
// AspectJAfterReturningAdvice
// AspectJAfterThrowingAdvice
// AspectJAroundAdvice
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
- ConfigBeanDefinitionParser#parsePointcut
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
String id = pointcutElement.getAttribute(ID);
String expression = pointcutElement.getAttribute(EXPRESSION);
AbstractBeanDefinition pointcutDefinition = null;
try {
this.parseState.push(new PointcutEntry(id));
// 此处创建一个 AspectJExpressionPointcut 类对应的BeanDefinition对象,处理 pointcut
pointcutDefinition = createPointcutDefinition(expression);
// ... 省略
}
finally {
this.parseState.pop();
}
return pointcutDefinition;
}
↓↓↓↓↓
protected AbstractBeanDefinition createPointcutDefinition(String expression) {
// 创建一个 AspectJExpressionPointcut 类对应的BeanDefinition对象
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanDefinition.setSynthetic(true);
// 设置切入点表达式
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
return beanDefinition;
}
- spring-aop.xml配置文件:
<aop:config>
<aop:aspect ref="myAdvice">
<aop:after method="after" pointcut="execution(* *..*.*ServiceImpl.*(..))" />
<aop:before method="before" pointcut="execution(* *..*.*ServiceImpl.*(..))" />
</aop:aspect>
</aop:config>
- ConfigBeanDefinitionParser#parseAspect:
private void parseAspect(Element aspectElement, ParserContext parserContext) {
String aspectId = aspectElement.getAttribute(ID);
String aspectName = aspectElement.getAttribute(REF);
try {
// 省略...
// 获取<aop:aspect>标签的所有子标签
NodeList nodeList = aspectElement.getChildNodes();
boolean adviceFoundAlready = false;
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
// 判断是否是<aop:before>、<aop:after>、<aop:after-returning>、<aop:after-throwing method="">、<aop:around method="">这五个标签
if (isAdviceNode(node, parserContext)) {
// 省略...
// 解析<aop:before>等五个子标签,主要完成三件事:
// 1、根据织如方式(before、after这些)创建RootBeanDefinition,名为adviceDef的advice定义
// 2、将上一步创建的RootBeanDefinition写入一个新的RootBeanDefinition,构造一个新的对象,名为advisorDefinition,即advisor定义
// 3、将advisorDefinition注册到DefaultListableBeanFactory中
AbstractBeanDefinition advisorDefinition = parseAdvice(
aspectName, i, aspectElement, (Element) node, parserContext, beanDefinitions, beanReferences);
beanDefinitions.add(advisorDefinition);
}
}
AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition(
aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);
parserContext.pushContainingComponent(aspectComponentDefinition);
// 得到所有<aop:aspect>下的<aop:pointcut>子标签
List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, POINTCUT);
for (Element pointcutElement : pointcuts) {
// 解析<aop:pointcut>子标签
parsePointcut(pointcutElement, parserContext);
}
parserContext.popAndRegisterContainingComponent();
}
finally {
this.parseState.pop();
}
}
- ConfigBeanDefinitionParser#parseAdvice:产生了8个BeanDefinition
private AbstractBeanDefinition parseAdvice(String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext, List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
try {
this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));
// create the method factory bean
// 第一个:MethodLocatingFactoryBean封装了通知功能对应的方法名称,在该类中可以对字符串的method方法转成Method对象
RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class);
methodDefinition.getPropertyValues().add("targetBeanName", aspectName);
// 设置MethodLocatingFactoryBean的methodName为<aop:after>标签的method属性值(也就是advice方法名称)
methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method"));
methodDefinition.setSynthetic(true);
// create instance factory definition
// 第二个:创建可以封装通知功能对应Bean实例的工厂BeanDefinition
// SimpleBeanFactoryAwareAspectInstanceFactory里面含有BeanFactory的引用,可以通过Bean的名称,去BeanFactory中获取对象
RootBeanDefinition aspectFactoryDef =
new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class);
// 设置SimpleBeanFactoryAwareAspectInstanceFactory的aspectBeanName为advice类的引用名称
aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);
aspectFactoryDef.setSynthetic(true);
// 以上的两个BeanDefinition的作用主要是通过反射调用Advice对象的指定方法
// method.invoke(obj,args)
// register the pointcut
// 第三~七个:通知增强类的BeanDefinition对象(核心)
AbstractBeanDefinition adviceDef = createAdviceDefinition(
adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef,
beanDefinitions, beanReferences);
// configure the advisor
// 第八个:通知器类的BeanDefinition对象
RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class);
advisorDefinition.setSource(parserContext.extractSource(adviceElement));
// 给通知器类设置Advice对象属性值
advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef);
if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
advisorDefinition.getPropertyValues().add(
ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
}
// register the final advisor
parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);
return advisorDefinition;
}
finally {
this.parseState.pop();
}
}
↓↓↓↓↓
private AbstractBeanDefinition createAdviceDefinition(Element adviceElement, ParserContext parserContext, String aspectName, int order, RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef, List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {
// 根据通知类型的不同,分别创建对应的BeanDefinition对象
// 创建第三~七个BeanDefinition
RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext));
adviceDefinition.setSource(parserContext.extractSource(adviceElement));
adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName);
adviceDefinition.getPropertyValues().add(DECLARATION_ORDER_PROPERTY, order);
if (adviceElement.hasAttribute(RETURNING)) {
adviceDefinition.getPropertyValues().add(
RETURNING_PROPERTY, adviceElement.getAttribute(RETURNING));
}
if (adviceElement.hasAttribute(THROWING)) {
adviceDefinition.getPropertyValues().add(
THROWING_PROPERTY, adviceElement.getAttribute(THROWING));
}
if (adviceElement.hasAttribute(ARG_NAMES)) {
adviceDefinition.getPropertyValues().add(
ARG_NAMES_PROPERTY, adviceElement.getAttribute(ARG_NAMES));
}
// 设置构造参数
ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues();
// 设置第一个构造参数:方法工厂对象的BeanDefinition
cav.addIndexedArgumentValue(METHOD_INDEX, methodDef);
// 解析<aop:before>、<aop:after>、<aop:after-returning>标签中的pointcut或者pointcut-ref属性
Object pointcut = parsePointcutProperty(adviceElement, parserContext);
// 设置第二个构造参数:切入点BeanDefinition
if (pointcut instanceof BeanDefinition) {
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcut);
beanDefinitions.add((BeanDefinition) pointcut);
}
else if (pointcut instanceof String) {
RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String) pointcut);
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);
beanReferences.add(pointcutRef);
}
// 设置第三个构造参数:实例工厂BeanDefinition
cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef);
return adviceDefinition;
}
↓↓↓↓↓
private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) {
// 获取标签名称,比如aop:before标签对应的标签名是before
String elementName = parserContext.getDelegate().getLocalName(adviceElement);
// 处理<aop:before>标签
if (BEFORE.equals(elementName)) {
return AspectJMethodBeforeAdvice.class;
}
// 处理<aop:after>标签
else if (AFTER.equals(elementName)) {
return AspectJAfterAdvice.class;
}
// 处理<aop:after-returning>标签
else if (AFTER_RETURNING_ELEMENT.equals(elementName)) {
return AspectJAfterReturningAdvice.class;
}
// 处理<aop:after-throwing>标签
else if (AFTER_THROWING_ELEMENT.equals(elementName)) {
return AspectJAfterThrowingAdvice.class;
}
// 处理<aop:aroud>标签
else if (AROUND.equals(elementName)) {
return AspectJAroundAdvice.class;
}
else {
throw new IllegalArgumentException("Unknown advice kind [" + elementName + "].");
}
}
产生AOP代理流程分析
AspectJAwareAdvisorAutoProxyCreator的继承体系
|--BeanPostProcessor
postProcessBeforeInitialization--初始化之前调用
postProcessAfterInitialization--初始化之后调用
|--InstantiationAwareBeanPostProcessor
postProcessBeforeInstantiation--实例化之前调用
postProcessAfterInstantiation--实例化之后调用
InstantiationPropertyValues--后置处理属性值
|--SmartInstantiationAwareBeanPostProcessor
predictBeanType
determineCandidateConstructors
getEarlyBeanReference
|--AbstractAutoProxyCreator
postProcessBeforeInitialization
postProcessAfterInitialization--AOP功能入口
postProcessBeforeInitialization
postProcessAfterInitialization
postProcessPropertyValues
...
|--AbstractAdvisorAutoProxyCreator
getAdvicesAndAdvisorsForBean
findEligibleAdvisors
findCandidateAdvisors
findAdvisorsThatCanApply
|--AspectJAwareAdvidorAutoProxyCreator
extendAdvisors
sortAdvisors
找入口
- AbstractAutoProxyCreator类的
postProcessAfterInitialization
方法第6行代码
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
// cacheKey就是beanName或者beanClass,拿到bean的名字
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 使用动态代理技术,产生代理对象
// bean : 目标对象
// beanName :目标对象名称
// cacheKey:就是beanName或者beanClass
如果需要的情况下进行包装,那么在什么情况下需要包装呢?
//点击进入 wrapIfNecessary
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
流程解析
- AbstractAutoProxyCreator#wrapIfNecessary:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 如果已经增强了,则不需要再生成代理了
// 看增强过的bean有没有我们的bean, 返回false
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// isInfrastructureClass方法:Advice/Pointcut/Advisor/AopInfrastructureBean接口的beanClass不进行代理
// shouldSkip方法:对beanName为aop内的切面beanName也不进行代理,此处可查看子类复写的shouldSkip()方法
// 看增强过的bean有没有我们的bean, 返回false
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 查找对代理类相关的advisor对象集合,此处就与ponit-cut表达式有关了
// execution(* *..*.method(args))
// 第一步:查找候选Advisor(增强器)
// 第二步:针对目标对象获取合适的Advisor(增强器)
// 创建一个代理对象,获取当前bean的增强器有哪些.
// 重点
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 对相应的advisor不为空才采取代理
// 如果这个bean有增强器,就不为空
if (specificInterceptors != DO_NOT_PROXY) {
// 把当前已经增强过的bean保存,保存当前bean在advisedBeans中
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 通过jdk动态代理或者cglib动态代,产理生代理对象
// 第三步:针对目标对象产生代理对象
// 如果当前bean有了增强器,那么就创建代理对象,增强此bean(如果当前bean需要增强,创建当前bean的代理对象)
// 点击进入 createProxy跟进去,看如何创建代理对象
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;
}
↓↓↓↓↓
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);
// 如果没有使用CGLib代理
// isProxyTargetClass就是判断aop:config标签的ProxyTargetClass属性,默认是false
if (!proxyFactory.isProxyTargetClass()) {
// 是否可能使用CGLib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 查看beanClass对应的类是否含有InitializingBean.class/DisposableBean.class/Aware.class接口
// 无则采用JDK动态代理,有则采用CGLib动态代理
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 将Advice和Advisor都适配成Advisor,方便后面统一处理
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 把增强器(通知方法)保存到proxyFactory中
proxyFactory.addAdvisors(advisors);
// 此处的targetSource一般为SingletonTargetSource
proxyFactory.setTargetSource(targetSource);
// 空的实现
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
// 是否设置预过滤模式,此处针对本文为true
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 获取使用JDK动态代理或者CGlib动态代理产生的对象
// 重点方法:用proxyFactory.getProxy代理工厂为我们创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
- ProxyFactory#getProxy:
public Object getProxy(@Nullable ClassLoader classLoader) {
// 1、创建JDK方式的AOP代理或者CGLib方式的AOP代理
// 2、调用具体的AopProxy来创建Proxy代理对象
return createAopProxy().getProxy(classLoader);
}
- ProxyCreatorSupport#createAopProxy:
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
// 创建JDK方式的AOP代理或者CGLib方式的AOP代理
return getAopProxyFactory().createAopProxy(this);
}
- 小结:
- 1、产生代理对象流程:先要获取AopProxyFactory(DefaultAopProxyFactory),接下来去产生AopProxy(JDKDynamicAopProxy、CglibDynamicAopProxy)
- 2、AopProxy,本身即是产生代理对象(Proxy)直接工厂,又是代理对象调用时需要的InvocationHandler实现类。
- DefaultAopProxyFactory#createAopProxy:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
// 省略...
// 如果目标类是接口或者目标类是Proxy的子类,则使用JDK动态代理方式
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用Cglib动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
// 默认使用JDK动态代理
return new JdkDynamicAopProxy(config);
}
}
- JdkDynamicAopProxy#getProxy:
// 实现了AopProxy的接口功能
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
// 获取完整的代理接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
// 调用JDK动态代理方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
AOP代理对象执行流程
找入口
- 主要去针对Jdk产生的动态代理对象进行分析,其实就是去分析InvocationHandler的invoke方法。分析入口就是 JdkDynamicAopProxy#invoke方法:
// JdkDynamicAopProxy实现了InvocationHandler接口
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 省略...
try {
// 省略...
// Get the interception chain for this method.
// 获取针对该目标对象的所有增强器(advisor)
// 这些advisor都是有顺序的,他们会按照顺序进行链式调用
// 将Advisor转换成MethodInterceptor
// 此处获取到的都是Advice
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// 省略...
// 检查是否我们有一些通知。
// 如果我们没有,我们可以直接对目标类进行反射调用,避免创建MethodInvocation类
else {
// 我们需要创建一个方法调用
// proxy:生成的动态代理对象,target:目标对象,method:目标方法,args:目标方法参数,targetClass:目标类对象
// chain: AOP拦截器执行链 是一个MethodInterceptor的集合
// 这个链条的获取过程参考我们上一篇文章的内容
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// Proceed to the joinpoint through the interceptor chain.
// 通过拦截器链进入连接点
// 开始执行AOP的拦截过程
retVal = invocation.proceed();
}
// 省略...
return retVal;
}
// finally 省略...
}
流程解析
- 一个目标对象,如果被多个增强功能给增强的话,那么增强功能的执行顺序是有两个保证:
- 如果通知类型相同的增强功能的执行顺序,由XML中配置的顺序所影响;
- 如果是不同通知类型相同的增强功能的执行顺序,由对应的MethodInterceptor的实现来保证顺序,比如MethodBeforeAdviceInterceptor,就是先不管其他的通知功能,先执行自己的通知功能。
- DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
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.
// 返回值集合,里面装的都是Interceptor或者它的子接口MethodInterceptor
List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
// 获取目标类的类型
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
// 是否有引介
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
// advisor适配器注册中心
// MethodBeforeAdviceAdapter:将Advisor适配成MethodBeforeAdvice
// AfterReturningAdviceAdapter:将Advisor适配成AfterReturningAdvice
// ThrowsAdviceAdapter:将Advisor适配成ThrowsAdvice
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 去产生代理对象的过程中,针对该目标方法获取到的所有合适的Advisor集合
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 如果该Advisor可以对目标类进行增强,则进行后续操作
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
// 获取方法匹配器,该方法匹配器可以根据指定的切入点表达式进行方法匹配
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
// 使用方法匹配器工具类进行方法匹配
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
// 将advisor转成MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// MethodMatcher接口通过重载定义了两个matches()方法
// 两个参数的matches()被称为静态匹配,在匹配条件不是太严格时使用,可以满足大部分场景的使用
// 称之为静态的主要是区分为三个参数的matches()方法需要在运行时动态的对参数的类型进行匹配;
// 两个方法的分界线就是boolean isRuntime()方法
// 进行匹配时先用两个参数的matches()方法进行匹配,若匹配成功,则检查boolean isRuntime()的返回值
// 若为true,则调用三个参数的matches()方法进行匹配(若两个参数的都匹配不中,三个参数的必定匹配不中)
// 需要根据参数动态匹配
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 {
// 通过AdvisorAdapterRegistry将Advisor都适配成MethodInterceptor类型
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
- DefaultAdvisorAdapterRegistry#getInterceptors:
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
// 如果是advice是MethodInterceptor类型,则直接加到数组中
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
// 使用AdvisorAdapter适配器对advice进行适配
// 如果适配成功,则将advisor适配成MethodInterceptor,放入集合中
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]);
}
- ReflectiveMethodInvocation#proceed
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// 如果执行到链条的末尾 则直接调用连接点方法 即 直接调用目标方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取集合中的 MethodInterceptor
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 如果是InterceptorAndDynamicMethodMatcher类型(动态匹配)
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)) {
// 如果匹配则直接调用 MethodInterceptor的invoke方法
// 注意这里传入的参数是this 我们下面看一下 ReflectiveMethodInvocation的类型
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.
// 说明是适用于此目标方法的直接调用 MethodInterceptor的invoke方法
// 传入this即ReflectiveMethodInvocation实例
// 传入this进入 这样就可以形成一个调用的链条了
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
- AopUtils#invokeJoinpointUsingReflection
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
throws Throwable {
// Use reflection to invoke the method.
try {
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
// 省略 catch ...
}
事务流程源码分析
获取TransactionInterceptor的BeanDefinition
找入口
- AbstractBeanDefinitionParser#parse方法
@Override
@Nullable
public final BeanDefinition parse(Element element, ParserContext parserContext) {
// 调用子类的parseInternal获取BeanDefinition对象
AbstractBeanDefinition definition = parseInternal(element, parserContext);
if (definition != null && !parserContext.isNested()) {
try {
String id = resolveId(element, definition, parserContext);
if (!StringUtils.hasText(id)) {
parserContext.getReaderContext().error(
"Id is required for element '" + parserContext.getDelegate().getLocalName(element)
+ "' when used as a top-level tag", element);
}
String[] aliases = null;
if (shouldParseNameAsAliases()) {
String name = element.getAttribute(NAME_ATTRIBUTE);
if (StringUtils.hasLength(name)) {
aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
}
}
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
// 将处理<tx:advice>标签的类BeanDefinition对象,注册到IoC容器中
registerBeanDefinition(holder, parserContext.getRegistry());
if (shouldFireEvents()) {
BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
postProcessComponentDefinition(componentDefinition);
parserContext.registerComponent(componentDefinition);
}
}
catch (BeanDefinitionStoreException ex) {
String msg = ex.getMessage();
parserContext.getReaderContext().error((msg != null ? msg : ex.toString()), element);
return null;
}
}
return definition;
}
流程图
流程解析
执行TransactionInterceptor流程分析
找入口
TransactionInterceptor类实现了MethodInterceptor接口,所以入口方法是invoke
方法:
@Override
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
// 调用TransactionAspectSupport类的invokeWithinTransaction方法去实现事务支持
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
流程解析