Spring源码解析七 (AOP深度解析)
目录1. 目标bean实例化完成后调用初始化方法2. 初始化方法执行之后应用后处理器(BeanPostProcessor)3. 尝试扩展目标bean4. 获取所有适合目标bean的所有Advisor4.1从容器获取所有已注册的增强4.2寻找所有的增强中适用于目标bean的增强5. 创建代理(重点)5.1 获取AOP代理(JdkDynamicAopProxy/Cg...
目录
2. 初始化方法执行之后应用后处理器(BeanPostProcessor)
5.1 获取AOP代理(JdkDynamicAopProxy/CglibAopProxy)
在Spring容器中, bean实例化完成后, 会调用初始化方法; 在调用该bean实例的初始化方法前后会分别应用后处理器(BeanPostProcessors), 实际上是分别调用后处理器中postProcessBeforeInitialization()和postProcessAfterInitialization()方法, 尝试对bean进行扩展; 而AOP中的增强就是在调用后处理器中postProcessAfterInitialization()方法将增强进行织入的;
1. 目标bean实例化完成后调用初始化方法
AbstractAutowireCapableBeanFactory#initializeBean实现:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
...
if (mbd == null || !mbd.isSynthetic()) {
/**
* 应用后处理器(在bean初始化之前调用)
*/
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
/**
* 激活用户自定义的init方法, 完成初始化
*/
invokeInitMethods(beanName, wrappedBean, mbd);
}
...
if (mbd == null || !mbd.isSynthetic()) {
/**
* 后处理器应用(在bean初始化之后调用)
*/
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
2. 初始化方法执行之后应用后处理器(BeanPostProcessor)
(1) AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization实现:
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
//获取所有已注册的BeanPostProcessor,遍历执行每一个BeanPostProcessor中重写的postProcessAfterInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/**
* AOP应用:
* {@link org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(java.lang.Object, java.lang.String)}
*/
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
分析: 获取所有注册到容器中的后处理器, 进行遍历执行postProcessAfterInitialization()方法, 尝试对bean进行扩展; 当遍历到processor为AnnotationAwareAspectJAutoProxyCreator实例时, 开始尝试对bean进行增强织入
(2) AbstractAutoProxyCreator#postProcessAfterInitialization实现:
(AbstractAutoProxyCreator为AnnotationAwareAspectJAutoProxyCreator的父类)
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//根据给定的bean的class和name构建出个key,格式:beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
/**
* 如果条件符合,则为bean生成代理对象
*/
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
分析: 根据bean的class属性和bean名称创建缓存key, 如果目标bean没有缓存在earlyProxyReferences集合中, 则开始尝试扩展目标bean
3. 尝试扩展目标bean
AbstractAutoProxyCreator#wrapIfNecessary实现:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已经处理过(targetSourcedBeans存放已经增强过的bean)
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//advisedBeans的key为cacheKey,value为boolean类型,表示是否进行过代理
//对于已经处理过的bean,不需要再次进行处理,节省时间
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
/**
* 如果目标类代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理
* isInfrastructureClass(): 如果目标类继承自Advice、Pointcut、Advisor、AopInfrastructureBean
* 或者带有@Aspect注解,或被Ajc(AspectJ编译器)编译都会被认定为内部基础设置类, 从而该目标类将会跳过扩展
* shouldSkip(): 判断目标bean是否需要跳过{@link AspectJAwareAdvisorAutoProxyCreator#shouldSkip(java.lang.Class, java.lang.String)}
*/
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/**
* 获取所有适合该bean的增强Advisor
* {@link AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean(java.lang.Class, java.lang.String, org.springframework.aop.TargetSource)
*/
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果获取的增强不为null,则为该bean创建代理(DO_NOT_PROXY=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;
}
分析:
- 如果已经处理过,则直接返回目标bean
- 对于内部配置相关类, 也直接返回目标bean, 并且将该目标bean标记为false, 后面再获取该bean时就直接返回了
- 获取所有适合该bean的增强Advisor
- 创建代理类
4. 获取所有适合目标bean的所有Advisor
(1) AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean实现:
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
/**
* 获取合适的增强器
*/
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
//数组为空,返回null
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
(2) AbstractAdvisorAutoProxyCreator#findEligibleAdvisors实现:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
/**
* 1. 获取所有的增强
*/
List<Advisor> candidateAdvisors = findCandidateAdvisors();
/**
* 2. 寻找所有的增强中只用于bean的增强应用
*/
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
/**
* 3. 模版方法,由子类拓展增强器(用作子类对已经查找完成的增强器进行拓展)
* {@link AspectJAwareAdvisorAutoProxyCreator#extendAdvisors(java.util.List)}
*/
extendAdvisors(eligibleAdvisors);
/**
* 4. 如果获取的Advisor集合eligibleAdvisors不为空,则根据优先级进行排序
*/
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
分析:
- 从容器获取所有已注册的增强
- 寻找所有的增强中适用于目标bean的增强应用
- 模版方法,由子类拓展增强器(用作子类对已经查找完成的增强器进行拓展)
- 如果获取的Advisor集合eligibleAdvisors不为空,则根据优先级进行排序
4.1 从容器获取所有已注册的增强
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors实现:
@Override
protected List<Advisor> findCandidateAdvisors() {
/**
* 增强器两类处理:
* 1. 通过<aop>标签添加的增强,这部分会在解析配置文件的时候添加到Spring容器中,只需要获取当前容器中Advisor类型的bean就可以获取到该类增强;
* 2. 通过注解添加的增强,获取此类增强还需要对bean进行遍历解析
*/
/**
* 在这里调用父类方法加载配置文件中的AOP声明
*/
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
/**
* 获取Bean的注解增强的功能
*/
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
分析:
- 首先尝试加载配置文件中的AOP声明信息
- 接着加载使用注解配置的AOP声明信息
(1) AbstractAdvisorAutoProxyCreator#findCandidateAdvisors ==>BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans实现:
public List<Advisor> findAdvisorBeans() {
String[] advisorNames = this.cachedAdvisorBeanNames;
/**
* 如果advisorNames为null, 说明还没有加载配置文件中的AOP声明
* 如果advisorNames为{}, 说明在配置文件中没有进行AOP配置
*/
if (advisorNames == null) {
/**
* 1. 获取所有增强器的名称
*/
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
List<Advisor> advisors = new ArrayList<>();
/**
* 2. 遍历所有增强器的名称,将其实例化
*/
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
...
}
else {
try {
/**
* 实例化切面bean, 并添加到advisors集合中
*/
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
...
}
}
}
return advisors;
}
分析:
- 如果获取到了相关切面类, 则进行实例化解析
- 如果没有获取到则返回空集合
(2) BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors实现:
public List<Advisor> buildAspectJAdvisors() {
//先尝试从缓存中获取
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
/**
* advisors集合存储容器中所有的切面类中定义的增强/通知Advice (注意是增强/通知, 没有切入点)
*/
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//获取所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
/**
* 遍历所有的beanName,找出添加了@Aspect的类, 进行解析,注册 <===== 重点
*/
for (String beanName : beanNames) {
//不合法的bean则略过,由子类定义规则,默认返回true
if (!isEligibleBean(beanName)) {
continue;
}
//获取对应的bean类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
/**
* 如果存在@Aspect注解的类
*/
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
//保存bean类型以及@Aspect注解信息
AspectMetadata amd = new AspectMetadata(beanType, beanName);
//检查@Aspect注解的value值,验证生成的增强是否是单例
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
/**
* classAdvisors集合存储的是该切面类中的所有的增强/通知
* {@link ReflectiveAspectJAdvisorFactory#getAdvisors(MetadataAwareAspectInstanceFactory)}
*/
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
//如果bean是单例,则缓存bean的增强器
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
//bean非单例,只能缓存bean对应的增强器创建工厂
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
/**
* 切面创建模式非单例
*/
else {
//如果切面是非单例,但是bean是单例,抛出异常
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
//获取所有切面
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
/**
* 如果不是第一次解析切面,证明增强器已经被缓存过了,会执行下面的代码,查询缓存
*/
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
//记录在缓存中
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
分析:
- 先尝试从缓存中获取, 如果获取成功则直接返回
- 如果没有从缓存获取到, 则遍历所有已注册的beanName, 对于添加@Aspect的类进行解析, 获取到该切面中的所有增强/通知(解析过程比较复杂,这里不再赘述, 感兴趣的可以自己看一下)
- 将解析之后的所有增强存储在List集合中, 并加入缓存, 后面可以直接通过缓存获取
4.2 寻找所有的增强中适用于目标bean的增强
AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply ==> AopUtils#findAdvisorsThatCanApply实现
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
/**
* eligibleAdvisors: 存储可以应用于目标类的增强
* canApply(candidate, clazz): 判断候选增强是否适用于目标类
*/
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;
}
5. 创建代理(重点)
AbstractAutoProxyCreator#createProxy实现:
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);
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);
}
/**
* 通过proxyFactory获取AopProxy
*/
return proxyFactory.getProxy(getProxyClassLoader());
}
分析:
- 将增强相关信息封装到ProxyFactory实例中
- 通过proxyFactory获取代理对象, 并返回
ProxyFactory#getProxy(java.lang.ClassLoader)实现:
public Object getProxy(@Nullable ClassLoader classLoader) {
/**
* 1. 代理类获取:
*{@link ProxyCreatorSupport#createAopProxy()}
* createAopProxy():
* ProxyFactory的父类ProxyCreatorSupport中的方法,父类ProxyCreatorSupport中维护着变量AopProxyFactory,
* DefaultAopProxyFactory是AopProxyFactory(接口)的实现类, 通过DefaultAopProxyFactory#createAopProxy()根据条件获取JdkDynamicAopProxy或CglibAopProxy实例
*
* 2. 代理目标类:
* JDK动态代理
* {@link JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)}
* CGLIB动态代理
* {@link CglibAopProxy#getProxy(java.lang.ClassLoader)}
* getProxy(classLoader): 生成代理对象
*/
return createAopProxy().getProxy(classLoader);
}
5.1 获取AOP代理(JdkDynamicAopProxy/CglibAopProxy)
ProxyCreatorSupport#createAopProxy实现:
protected final synchronized AopProxy createAopProxy() {
...
/**
* {@link org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy(org.springframework.aop.framework.AdvisedSupport)}
* ProxyFactory的父类ProxyCreatorSupport中的方法,父类ProxyCreatorSupport中维护着变量AopProxyFactory,
* DefaultAopProxyFactory是AopProxyFactory(接口)的实现类, 通过DefaultAopProxyFactory#createAopProxy()
* 根据条件获取JdkDynamicAopProxy或CglibAopProxy实例, 所以创建代理类是可以传递this
*/
return getAopProxyFactory().createAopProxy(this);
}
分析: 前面将增强相关配置信息封装到ProxyFactory中, 而ProxyCreatorSupport是ProxyFactory的父类, 父类ProxyCreatorSupport中维护着变量AopProxyFactory, DefaultAopProxyFactory是AopProxyFactory(接口)的实现类, 通过DefaultAopProxyFactory#createAopProxy()方法根据条件获取JdkDynamicAopProxy或CglibAopProxy实例, 所以创建代理类时通过传递this来传递增强/通知信息
DefaultAopProxyFactory#createAopProxy实现:
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
/**
* config.isOptimize(): 代理是否应执行积极的优化 (默认:false)
* config.isProxyTargetClass(): 是否直接代理目标类以及任何接口 (默认:false); 如果配置<aop:aspectj-autoproxy proxy-target-class="true" />则强制使用CGLIB代理
* hasNoUserSuppliedProxyInterfaces(config): 目标类是否有实现的接口,没有的话返回true (JDK动态代理基于接口,所以只有目标类存在接口才会使用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);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
分析: 该方法中根据条件去判断使用哪一种代理方式, 因此可知Spring中没有默认的生成代理的方式, Spring会根据目标对象的条件以及相关配置使用对应的动态代理, 这里注意, 并不是我们配置了<aop:aspectj-autoproxy proxy-target-class="true" />, 就Spring就一定会使用CGLIB动态代理, 如果目标类是接口,或者目标类是一个代理类, 那么即使做了上面的配置, Spring也会使用JDK动态代理;
5.2 通过AOP代理采用不同的策略为目标对象创建代理对象
对于JDK动态代理和CGLIB动态代理不太明白的伙伴可以看这两篇博客:
5.2.1 使用JDK动态代理创建代理对象
JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)实现:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
/**
* 1. 获取所有被代理的接口(JDK动态代理基于接口)
*/
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
/**
* 2. 遍历所有代理接口中的方法,查找到某个接口中如果存在equals()和hashCode()方法,则进行标识, 如果标识为true,则后面会对这两个方法进行代理
*/
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
/**
* 3. 创建代理对象并返回
* 注意: 在newProxyInstance()方法中传入的是this, 说明JdkDynamicAopProxy实现了InvocationHandler接口,
* 并重写的invoke()方法, 那么增强的织入是在invoke()方法中实现的
* {@link JdkDynamicAopProxy#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])}
*/
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
分析:
- 获取所有被代理的接口(JDK动态代理基于接口)
- 遍历所有代理接口中的方法, 查找到目标类的某个接口中如果存在equals()和hashCode()方法, 则进行标识(说明目标类中的这两个方法时实现该接口的而不是Object的); 如果标识为true, 则后面会对这两个方法进行代理, 如果为false, 则后面忽略目标类中的equals()和hashCode()方法,认为这两个方法是基于超类Object的, 不进行增强
- 创建代理对象并返回; 注意: 在newProxyInstance()方法中传入的是this, 说明JdkDynamicAopProxy实现了InvocationHandler接口, 并重写的invoke()方法, 那么增强的织入是在invoke()方法中实现的
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable
JdkDynamicAopProxy#invoke实现(重点):
@Override
@Nullable
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)) {
//目标本身不实现equals()方法
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
//目标本身不实现hashCode()方法
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//目标类实例
target = targetSource.getTarget();
//目标类Class
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取此方法的拦截链
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);
/**
* 通过拦截器链进入连接点
* {@link ReflectiveMethodInvocation#proceed()}
*/
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()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
AopContext.setCurrentProxy(oldProxy);
}
}
}
分析:
- 对于不需要增强的类直接返回
- 创建一个MethodInvocation实例,该实例中维护这代理方法和拦截器链相关信息
- 通过拦截器链进入连接点, 执行增强方法, 以及切入点方法 (织入) <==== 重点
ReflectiveMethodInvocation#proceed实现:
@Override
@Nullable
public Object proceed() throws Throwable {
/**
* currentInterceptorIndex: 当前需要执行拦截器在集合中位置, 默认为-1
* 当最后一个拦截器执行完之后, 回调该方法才会执行切入点方法
*/
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
/**
* 执行切入点
*/
return invokeJoinpoint();
}
/**
* 根据索引获取到拦截器; 每调用一次proceed(), 会获取到下一个拦截器,然后进行处理
*/
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
/**
* 如果获取到的增强是内部框架类
*/
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//如果动态匹配失败,则跳过该拦截器,执行下一个(递归)
return proceed();
}
}
else {
/**
* 执行每个拦截器, 会先执行前置通知,再执行后置通知
* 后置增强: {@link AspectJAfterAdvice#invoke(org.aopalliance.intercept.MethodInvocation)}
* 前置增强: {@link MethodBeforeAdviceInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)}
*/
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
分析:
- 当拦截器链中最后一个拦截器执行完之后, 回调该方法会执行切入点方法
- 根据索引获取到拦截器; 每调用一次proceed(), 会获取到下一个拦截器, 然后进行处理
- 如果获取到的增强是内部框架类, 则进行匹配, 如果匹配成功才会执行, 匹配失败直接执行下一个拦截器
- 激活拦截器
切入点方法执行:
ReflectiveMethodInvocation#invokeJoinpoint ==> AopUtils#invokeJoinpointUsingReflection实现:
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
try {
/**
* 利用反射执行目标方法
*/
ReflectionUtils.makeAccessible(method);
return method.invoke(target, args);
}
...
}
后置通知方法执行:
AspectJAfterAdvice#invoke实现:
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
/**
* 如果是后置增强,则先调用MethodInvocation#proceed()方法, 执行其他增强, 等其他所有增强和切入点方法执行完成后,再执行后置增强
* {@link ReflectiveMethodInvocation#proceed()}
*/
return mi.proceed();
}
finally {
/**
* 当所有拦截器执行完成之后,执行后置增强
* 后置增强的执行是在finally块中,因此, 及时目标方法出现异常, 后置通知也会执行
* 同理也可以知道, 异常增强方法是在catch块中执行的
*/
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
分析: 这里是先调用MethodInvocation#proceed(), 先去执行其他拦截器, 等所有的拦截器执行结束会执行切入点方法, 等切入点方法执行完成之后, 才会执行该后置通知方法; 注意, 后置通知的执行是在finally块中执行的, 所以即使切入点方法执行时出现异常, 后置通知也仍然会执行;
前置通知方法执行:
MethodBeforeAdviceInterceptor#invoke实现:
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
/**
* 如果是前置通知,则先执行增强方法, 再调用proceed()去获取其他拦截器
*/
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
/**
* 调用MethodInvocation#proceed()执行切入点方法
* {@link ReflectiveMethodInvocation#proceed()}
*/
return mi.proceed();
}
分析: 对于前置通知, 就很简单了, 先执行前置通知方法, 然后调用MethodInvocation#proceed()执行去切入点方法 (前提是所有的拦截器都已经激活)
5.2.2 使用CGLIB动态代理创建代理对象
CglibAopProxy#getProxy(java.lang.ClassLoader)实现:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
//获取目标类Class对象
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
//设置目标类为代理父类(CGLIB基于继承实现代理)
Class<?> proxySuperClass = rootClass;
//如果目标类也是CGLIB代理类,则设目标类的父类为代理父类
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
//获取目标类的所有接口
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// 验证类,根据需要编写日志消息
validateClassIfNecessary(proxySuperClass, classLoader);
//创建并配置CGLIB增强实例
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));
/**
* 获取回调类信息,即增强
*/
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
/**
* 生成代理类并创建代理实例
* {@link ObjenesisCglibAopProxy#createProxyClassAndInstance(org.springframework.cglib.proxy.Enhancer, org.springframework.cglib.proxy.Callback[])}
*/
return createProxyClassAndInstance(enhancer, callbacks);
}
...
}
@Override
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
//创建代理类
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
/**
* 实例化代理类
*/
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
...
}
if (proxyInstance == null) {
try {
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
}
...
}
((Factory) proxyInstance).setCallbacks(callbacks);
/**
* 代理类的执行方法
* {@link DynamicAdvisedInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], org.springframework.cglib.proxy.MethodProxy)}
*/
return proxyInstance;
}
分析: 对于CGLIB代理, 是基于目标类的, 给目标类生成一个子类, 重写目标类的方法, 在执行代理类的方法时会执行DynamicAdvisedInterceptor#intercept()方法; AOP增强的织入也是在这里面完成的;
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);
/**
* 1. 获取拦截器链
*/
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
//检查我们是否只有一个InvokerInterceptor:没有真正的增强,只是对目标的发射调用。
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
/**
* 跳过创建MethodInvocation的方法:直接调用目标即可
* 请注意,最终的调用者必须是InvokerInterceptor,因此我们知道它仅对目标执行反射操作,并且不执行热交换或奇特代理
*/
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
/**
* 2.创建一个方法调用,执行目标方法
* (1) new CglibMethodInvocation():CglibMethodInvocation实例继承ReflectiveMethodInvocation
* (2) proceed():此处与JDK动态代理一样,都是通过ReflectiveMethodInvocation#proceed()方法完成增强的织入
*/
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
/**
* 3. 处理返回值
*/
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);
}
}
}
分析:
- 获取拦截器链
- 创建方法调用,执行目标方法; new CglibMethodInvocation(..): CglibMethodInvocation实例继承ReflectiveMethodInvocation; proceed(): 此处与JDK动态代理一样, 都是通过ReflectiveMethodInvocation#proceed()方法完成增强的织入
- 处理返回值
ReflectiveMethodInvocation#proceed实现:
@Override
@Nullable
public Object proceed() throws Throwable {
/**
* currentInterceptorIndex: 当前需要执行拦截器在集合中位置, 默认为-1
* 当最后一个拦截器执行完之后, 回调该方法才会执行切入点方法
*/
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
/**
* 执行切入点
*/
return invokeJoinpoint();
}
/**
* 根据索引获取到拦截器; 每调用一次proceed(), 会获取到下一个拦截器,然后进行处理
*/
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
/**
* 如果获取到的增强是内部框架类
*/
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
//如果动态匹配失败,则跳过该拦截器,执行下一个(递归)
return proceed();
}
}
else {
/**
* 执行每个拦截器, 会先执行前置通知,再执行后置通知
* 后置增强: {@link AspectJAfterAdvice#invoke(org.aopalliance.intercept.MethodInvocation)}
* 前置增强: {@link MethodBeforeAdviceInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)}
*/
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
分析: 对于两种动态代理方法, 增强的织入逻辑的实现都是一样的, 这里就不再赘述了, 可以参考上面JDK动态代理的织入过程
至此, Spring中AOP的实现解析完成!
相关文章:
Spring源码解析二 (IOC容器初始化方式一:XmlBeanFactory)
Spring源码解析三 (IOC容器初始化方式二:ClassPathXmlApplicationContext)
Spring源码解析四 (IOC容器初始化方式三: AnnotationConfigApplicationContext[包路径配置方式])
Spring源码解析五 (IOC容器初始化方式四: AnnotationConfigApplicationContext[Java配置类方式])
更多推荐
所有评论(0)