上篇文章学习了动态代理的使用以及spring中动态代理的基础使用和aop的基本概念,本篇文章首先学习spring中ProxyFactory原理以及aop源码
OrderService target = new OrderService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.setInterfaces(OrderInterface.class);
proxyFactory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
});
OrderInterface proxy = (OrderInterface) proxyFactory.getProxy();
proxy.test();
System.out.println(proxy.getClass().getName());
org\springframework\aop\framework\ProxyFactory.java
org.springframework.aop.framework.ProxyCreatorSupport
ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术:
org.springframework.aop.framework.DefaultAopProxyFactory
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 如果ProxyFactory的isOptimize为true,
// 或者isProxyTargetClass为true,
// 或者被代理对象没有实现接口,
// 或者只实现了SpringProxy这个接口
// 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理
// 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
// config就是ProxyFactory对象
// optimize为true,或proxyTargetClass为true,或用户没有给ProxyFactory对象添加interface
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.");
}
// targetClass是接口,直接使用Jdk动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// cgllib
return new ObjenesisCglibAopProxy(config);
}
else {
// jdk
return new JdkDynamicAopProxy(config);
}
}
在构造JdkDynamicAopProxy对象时,会先拿到被代理对象自己所实现的接口,并且额外的增加SpringProxy、Advised、DecoratingProxy三个接口,组合成一个Class[],并赋值给proxiedInterfaces属性
org.springframework.aop.framework.JdkDynamicAopProxy
public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
Assert.notNull(config, "AdvisedSupport must not be null");
if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
throw new AopConfigException("No advisors and no TargetSource specified");
}
// config是ProxyFactory对象
this.advised = config;
// 设置JDK动态代理所要代理的接口
// 先拿到被代理对象自己所实现的接口,并且额外的增加SpringProxy、Advised、DecoratingProxy三个接口,组合成一个Class[],并赋值给proxiedInterfaces属性
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
// 检查这些接口中是否定义了equals()、hashcode()方法
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
并且检查这些接口中是否定义了equals()、hashcode()方法
org.springframework.aop.framework.JdkDynamicAopProxy
private void findDefinedEqualsAndHashCodeMethods(Class>[] proxiedInterfaces) {
// 判断被代理的接口中是否定义了equals()、hashCode()方法,如果程序员在接口中手动定义了这两个方法,则也会进行代理
// 否则这两个方法是不会走代理逻辑的
for (Class> proxiedInterface : proxiedInterfaces) {
Method[] methods = proxiedInterface.getDeclaredMethods();
for (Method method : methods) {
if (AopUtils.isEqualsMethod(method)) {
this.equalsDefined = true;
}
if (AopUtils.isHashCodeMethod(method)) {
this.hashCodeDefined = true;
}
if (this.equalsDefined && this.hashCodeDefined) {
return;
}
}
}
}
执行Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this)
,得到代理对象,JdkDynamicAopProxy作为InvocationHandler,代理对象在执行某个方法时,会进入到JdkDynamicAopProxy的**invoke()**方法中
@Override
public Object getProxy() {
return getProxy(ClassUtils.getDefaultClassLoader());
}
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
// this实现了InvocationHandler
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader)
获取被代理类
创建Enhancer对象
设置Enhancer的superClass为通过ProxyFactory.setTarget()所设置的对象的类
// 被代理类,代理类的父类
enhancer.setSuperclass(proxySuperClass);
设置Enhancer的interfaces为通过ProxyFactory.addInterface()所添加的接口,以及SpringProxy、Advised、DecoratingProxy接口
// 代理类额外要实现的接口
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
设置Enhancer的Callbacks为DynamicAdvisedInterceptor
// 获取和被代理类所匹配的Advisor
Callback[] callbacks = getCallbacks(rootClass);
Class>[] types = new Class>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
最后创建一个代理对象,代理对象在执行某个方法时,会进入到DynamicAdvisedInterceptor的intercept()方法中
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
在使用ProxyFactory创建代理对象之前,需要往ProxyFactory先添加Advisor
UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvisor(new PointcutAdvisor() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class> targetClass) {
return method.getName().equals("testAbc");
}
};
}
@Override
public Advice getAdvice() {
return new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
};
}
@Override
public boolean isPerInstance() {
return false;
}
});
UserInterface userService = (UserInterface) proxyFactory.getProxy();
userService.test();
或者
OrderService target = new OrderService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
//proxyFactory.setInterfaces(OrderInterface.class);
proxyFactory.addAdvice(new MethodInterceptor() {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("before...");
Object result = invocation.proceed();
System.out.println("after...");
return result;
}
});
OrderInterface proxy = (OrderInterface) proxyFactory.getProxy();
proxy.test();
System.out.println(proxy.getClass().getName());
}
不管是addAdvice还是addAdvisor最后都是转换成DefaultPointcutAdvisor
以JdkDynamicAopProxy动态代理为例,JdkDynamicAopProxy作为InvocationHandler,代理对象在执行某个方法时,会进入到JdkDynamicAopProxy的**invoke()**方法中
org.springframework.aop.framework.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 {
// 如果接口中没有定义equals()方法,那么则直接调用,不走代理
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();
}
//没用过 留作以后再说
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
// 得到代理对象的类型,而不是所实现的接口
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 如果 方法所在的类是接口 并且是Advised的子类,则直接调用下面的方法,这个方法在下面分析
// Service invocations on ProxyConfig with the proxy config...
// 也是直接调用Advised接口中的方法,不走代理逻辑
// 其实就是利用代理对象获取ProxyFactory中的信息
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
//是否对外暴露代理对象
// 如果ProxyFactory的exposeProxy为true,则将代理对象设置到currentProxy这个ThreadLocal中去
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);
// Get the interception chain for this method.
// 从Advised中根据方法名和目标类获取 AOP拦截器执行链 重点要分析的内容
// 代理对象在执行某个方法时,根据方法筛选出匹配的Advisor,并适配成Interceptor
// 代理对象在执行某个方法时,会把ProxyFactory中的Advisor拿出来和当前正在执行的方法进行匹配筛选
// 把和方法所匹配的Advisor适配成MethodInterceptor
List
在上面的方法中大致了说明了一下整个代理对象方法调用的执行过程,像equals和hashcode方法的调用,Advised子类的调用。重点就是在连接点处执行不同的通知类型的调用,即获取AOP拦截执行链的调用。下面我们要分析的就是这个过程:
this.advised.getInterceptorsAndDynamicInterceptionAdvice。
我们这里的advised是一个AdvisedSupport类型的实例,它可能是ProxyFactory的实例也可能是AspectJProxyFactory实例。我们进入到getInterceptorsAndDynamicInterceptionAdvice这个方法中去看一下:
public List
上面的方法的调用过程是先从缓存中获取,缓存中获取不到的话,再交给AdvisorChainFactory,通过调用AdvisorChainFactory中的getInterceptorsAndDynamicInterceptionAdvice方法来获取拦截器执行链,放入到缓存中。AdvisorChainFactory在SpringAOP中只有一个默认的实现类:DefaultAdvisorChainFactory,所以我们去这个DefaultAdvisorChainFactory类中看一下这个方法的内容。
org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
// 在这个方法中传入了三个实例,一个是Advised的实例 一个是目标方法 一个是目标类可能为null
// 想想我们在前面的文章中说过的,在Advised中都有什么内容
@Override
public List 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.
//这里用了一个单例模式 获取DefaultAdvisorAdapterRegistry实例
//在Spring中把每一个功能都分的很细,每个功能都会有相应的类去处理 符合单一职责原则的地方很多 这也是值得我们借鉴的一个地方
//AdvisorAdapterRegistry这个类的主要作用是将Advice适配为Advisor 将Advisor适配为对应的MethodInterceptor 我们在下面说明
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 从ProxyFactory中拿到所设置的Advice(添加时被封装成了DefaultPointcutAdvisor)
// 添加的时候会控制顺序
Advisor[] advisors = config.getAdvisors();
// 创建一个初始大小为 之前获取到的 通知个数的 集合
List interceptorList = new ArrayList<>(advisors.length);
// 如果目标类为null的话,则从方法签名中获取目标类
Class> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
// 循环 目标方法匹配的 通知
for (Advisor advisor : advisors) {
// 如果是PointcutAdvisor类型的实例 我们大多数的Advisor都是PointcutAdvisor类型的
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();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
// 如果匹配则将Advisor封装成为Interceptor
if (match) {
// 将Advisor适配为MethodInterceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
// MethodMatcher中的切点分为两种 一个是静态的 一种是动态的
// 如果isRuntime返回true 则是动态的切入点 每次方法的调用都要去进行匹配
// 而静态切入点则回缓存之前的匹配结果值
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
// 动态切入点 则会创建一个InterceptorAndDynamicMethodMatcher对象
// 这个对象包含MethodInterceptor和MethodMatcher 的实例
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)) {
// 将Advisor转换为Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
// 以上两种都不是
else {
// 将Advisor封装成为Interceptor
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
在上面这个方法中主要干了这几件事:
1、循环目标方法的所有Advisor
2、判断Advisor的类型
如果是PointcutAdvisor的类型,则判断此Advisor是否适用于此目标方法
如果是IntroductionAdvisor引介增强类型,则判断此Advisor是否适用于此目标方法
如果以上都不是,则直接转换为Interceptor类型。
在上面的三个步骤中都干了这样的一件事,将Advisor转换为Interceptor类型。这里用到了一个很重要的一个类:DefaultAdvisorAdapterRegistry。从类名我们可以看出这是一个Advisor的适配器注册类。它的源码如下:
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
//初始化了一个size为3的集合 因为下面就添加了三个AdvisorAdapter
private final List adapters = new ArrayList(3);
/**
* Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
*/
public DefaultAdvisorAdapterRegistry() {
//在SpringAOP中只默认提供了这三种通知类型的适配器
//为什么没有其他通知类型的呢?参考AbstractAspectJAdvice下面的几个通知类型
//前置通知适配器
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
//后置返回通知适配器
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
//后置异常通知适配器
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
//这个方法的作用主要是将Advice转换为Advisor的
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
//如果传入的实例是Advisor 则直接返回
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
//如果传入的实例不是 Advice类型 则直接抛出异常
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
//如果这个Advice是MethodInterceptor类型的实例,则直接包装为DefaultPointcutAdvisor
//DefaultPointcutAdvisor中的Pointcut为Pointcut.TRUE matches始终返回true
if (advice instanceof MethodInterceptor) {
return new DefaultPointcutAdvisor(advice);
}
//如果不是Advisor的实例 也不是MethodInterceptor类型的实例
//看看是不是 上面的那种通知类型适配器所支持的类型
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
//这个方法是将 Advisor转换为 MethodInterceptor
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List interceptors = new ArrayList(3);
//从Advisor中获取 Advice
Advice advice = advisor.getAdvice();
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
//转换为对应的 MethodInterceptor类型
//AfterReturningAdviceInterceptor MethodBeforeAdviceInterceptor ThrowsAdviceInterceptor
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
}
//新增的 Advisor适配器
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
所以this.advised.getInterceptorsAndDynamicInterceptionAdvice这个方法获取的是目标方法的AOP拦截器执行链。
我们接着说AOP对目标对象的拦截过程。下面的代码是我们要分析的重点:
在invoke方法中,如果获取到拦截器执行链不为空
/proxy:生成的动态代理对象
//target:目标对象
//method:目标方法
//args:目标方法参数
//targetClass:目标类对象
//chain: AOP拦截器执行链 是一个MethodInterceptor的集合
// 构造ReflectiveMethodInvocation对象
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class> targetClass, List interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
// 桥接方法
this.method = BridgeMethodResolver.findBridgedMethod(method);
// 转换参数
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
@Override
@Nullable
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// currentInterceptorIndex初始值为-1,每调用一个interceptor就会加1
// 当调用完了最后一个interceptor后就会执行被代理方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 下面会分析
return invokeJoinpoint();
}
// 获取集合中的 MethodInterceptor
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// 当前interceptor是InterceptorAndDynamicMethodMatcher,则先进行匹配,匹配成功后再调用该interceptor
// 如果没有匹配则递归调用proceed()方法,调用下一个interceptor
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)) {
// 如果匹配则直接调用 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,传入this,在内部会再次调用proceed()方法进行递归
// 比如MethodBeforeAdviceInterceptor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
invokeJoinpoint方法
@Nullable
protected Object invokeJoinpoint() throws Throwable {
// this.target 目标对象
// this.method 目标方法
// this.arguments 目标方法参数信息
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
@Nullable
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 (InvocationTargetException ex) {
// Invoked method threw a checked exception.
// We must rethrow it. The client won't see the interceptor.
throw ex.getTargetException();
}
catch (IllegalArgumentException ex) {
throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
method + "] on target [" + target + "]", ex);
}
catch (IllegalAccessException ex) {
throw new AopInvocationException("Could not access method [" + method + "]", ex);
}
}
MethodInterceptorChain
OK,我们在proceed()这个方法中看到了AOP对于目标方法的一个拦截的过程,其中很重要的一个点是调用MethodInterceptor的invoke方法。
我们先看一下MethodInterceptor的主要UML类图(由于我们在开发中使用AspectJ注解的方式越来越多,所以我们这里说的基本上都是基于AspectJ注解的):
从上图我们也可以看到不同的通知其实相当于不同的MethodInterceptor类型。
-------------
以上分析的是spring使用ProxyFactory进行代理对象的创建以及统一的拦截调用过程,下面是关于Aop的集成过程,也就是说aop是如果使用这些的。
首先我们想一下,我们在项目中是如何实现aop的,最主要的是开启spring aop,也就是 @EnableAspectJAutoProxy注解。
导入了AspectJAutoProxyRegistrar,他实现了ImportBeanDefinitionRegistrar,在之前文章配置类解析中我们知道在最后会执行configClass中的所有ImportBeanDefinitionRegistrar的registerBeanDefinitions方法
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注册一个AnnotationAwareAspectJAutoProxyCreator类型的Bean,beanName为AUTO_PROXY_CREATOR_BEAN_NAME
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 修改AnnotationAwareAspectJAutoProxyCreator中对应的属性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
这个注解主要就是往Spring容器中添加了一个AnnotationAwareAspectJAutoProxyCreator类型的Bean。看这个类的名字我们大概可以知道它主要是为AspectJ注解提供服务的类。这个类不得了了是一个相当厉害的类,在这个类中可以识别应用中的所有切面类,为目标类找寻合适的Advisor,将目标类变为代理类等功能。话不多说了,下面我们来简单的分析一下这个类。
首先我们来看一下这个类的类图:
AnnotationAwareAspectJAutoProxyCreator继承了AspectJAwareAdvisorAutoProxyCreator,AspectJAwareAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator非常强大以及重要,只要Spring容器中存在这个类型的Bean,就相当于开启了AOP,AbstractAdvisorAutoProxyCreator实际上就是一个BeanPostProcessor,所以在创建某个Bean时,就会进入到它对应的生命周期方法中,在某个Bean初始化之后,会调用父类AbstractAutoProxyCreator的postProcessAfterInitialization方法
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断是否是循环依赖提前进行了aop
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 进行aop
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
// 这个方法的主要作用就是创建代理对象
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经创建过了
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// advisedBeans表示已经判断过了的bean,false表示此bean不需要进行Aop
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 当前正在创建的Bean不用进行AOP,比如切面Bean
//isInfrastructureClass 判断是不是负责AOP基础建设的Bean,如果是AOP基础建设的Bean不能在这里被创建代理对象
//那么什么样的Bean是AOP的基础建设Bean呢?Advice、Pointcut、Advisor、AopInfrastructureBean类型的Bean
//以及含有Aspect注解的Bean
//shouldSkip这个方法是判断这个类型的Bean能不能被跳过,如果可以跳过,那么就不提前创建这个类
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 判断当前bean是否存在匹配的advice,如果存在则要生成一个代理对象
//getAdvicesAndAdvisorsForBean这个方法下面分析
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// advisedBeans记录了某个Bean已经进行过AOP了
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 创建代理对象
// 下面分析
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 如果不需要创建代理对象的话 这里缓存false
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
@Override
@Nullable
// targetSource 为null
protected Object[] getAdvicesAndAdvisorsForBean(
Class> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 寻找匹配的Advisor
List advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
// 如果获取的Advisor为空的话,则直接返回DO_NOT_PROXY 返回这个值的时候 是不创建代理对象
return DO_NOT_PROXY;
}
return advisors.toArray();
}
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected List findEligibleAdvisors(Class> beanClass, String beanName) {
// 找到所有的Advisor
// 获取Spring容器中的所有的通知方法 封装为Advisor集合
List candidateAdvisors = findCandidateAdvisors();
// 进行筛选
// 这一步就是为目标对象挑选合适的Advisor 即目标对象和切点表达式相匹配
List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
// 对Advisor进行排序,按Ordered接口、@Order注解进行排序
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
AspectJAwareAdvisorAutoProxyCreator重写了findCandidateAdvisors()方法,AbstractAdvisorAutoProxyCreator只能找到所有Advisor类型的Bean对象,但是AspectJAwareAdvisorAutoProxyCreator除开可以找到所有Advisor类型的Bean对象,还能把@Aspect注解所标注的Bean中的@Before等注解及方法进行解析,并生成对应的Advisor对象。
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
protected List findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 先调用父类的findCandidateAdvisors方法
// 先找到所有Advisor类型的Bean对象
List advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
// 再从所有切面中解析得到Advisor对象
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
protected List findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
//这个advisorRetrievalHelper 就是在 initBeanFactory方法中创建的BeanFactoryAdvisorRetrievalHelper
return this.advisorRetrievalHelper.findAdvisorBeans();
}
org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
// 这个方法的内容是从Spring容器中获取Advisor类型的Bean
public List findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
// 先看看之前是不是缓存过
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
// 上面的注释说的很清楚 这里不会初始化FactoryBean 为什么会这样说呢?因为提前导致FactoryBean类型的Bean被创建的话是会有问题的
// 从BeanFactory中获取所有的Advisor类型的Bean
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 这里进行赋值缓存
this.cachedAdvisorBeanNames = advisorNames;
}
// 如果没有Advisor类型的Bean的话 直接返回
// 如果你有特殊需求的话 可以实现Advisor接口,并向Spring容器中注入对应的Bean
if (advisorNames.length == 0) {
return new ArrayList<>();
}
// 这里是默认创建了一个 Advisor类型的集合
List advisors = new ArrayList<>();
for (String name : advisorNames) {
// 这里默认返回的是true
if (isEligibleBean(name)) {
// 如果是正在创建中的Bean 则跳过
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 从BeanFactory中获取对应的Bean 这里如果Bean还没创建 会导致Bean创建
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
//异常处理 略
}
}
}
}
return advisors;
}
上面找到所有Advisor类型的bean之后,下面是解析@Aspect @Before注解的
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
// 本方法会被多次调用,因为一个Bean在判断要不要进行AOP时,都会调用这个方法
public List buildAspectJAdvisors() {
// aspectBeanNames是用来缓存BeanFactory中所存在的切面beanName的,第一次为null,后面就不为null了,不为null表示之前就已经找到过BeanFactory中的切面了
List aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 把所有beanNames拿出来遍历,判断某个bean的类型是否是Aspect
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
// 注意看上面这个注释的内容:在这个场景下我们获取BeanClass的时候必须要小心处理,以免会提前初始化
// Bean,这些Bean在初始化之后会被Spring容器缓存起来,但是这些Bean可能还没有被织入。
Class> beanType = this.beanFactory.getType(beanName, false);
if (beanType == null) {
continue;
}
// 判断上面获取到的BeanClass是否带有Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
//创建切面元数据
//参考: https://blog.csdn.net/zknxx/article/details/79685290
AspectMetadata amd = new AspectMetadata(beanType, beanName);
// 如果@Aspect不是perthis、pertarget,那么一个切面只会生成一个对象(单例)
// 并且会将该切面中所对应的Advisor对象进行缓存
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 利用BeanFactoryAspectInstanceFactory来解析Aspect类
List classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 缓存切面所对应的所有Advisor对象
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
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);
// 利用PrototypeAspectInstanceFactory来解析Aspect类
// PrototypeAspectInstanceFactory的父类为BeanFactoryAspectInstanceFactory
// 这两个Factory的区别在于PrototypeAspectInstanceFactory的构造方法中会判断切面Bean是不是原型,除此之外没有其他区别
// 所以主要就是BeanFactoryAspectInstanceFactory来负责生成切面实例对象
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
// 如果切面已经找到过了,那么则遍历每个切面是否缓存了对应的Advisor,如果没有缓存则进行解析得到Advisor
List advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List 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;
}
以上是获取Spring容器中的所有的通知方法 封装为Advisor集合
最后我们再看看目标对象的创建过程:
// specificInterceptors 上面的方法中获取到的Advisor
// targetSource 为 new SingletonTargetSource(bean)
// 将Spring容器中创建出来的bean封装为了SingletonTargetSource
protected Object createProxy(Class> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
// 这里将目标Bean的Class设置为BeanDefinition中的一个属性
// 在使用JDK动态代理的时候 可能会用到这个属性 https://stackoverflow.com/questions/45463757/what-is-interface-based-proxying
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// 这里创建了一个新的 ProxyFactory
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
// 这里是 判断是否强制使用 cglib
if (proxyFactory.isProxyTargetClass()) {
// Explicit handling of JDK proxy targets (for introduction advice scenarios)
// 这里 判断是 使用jdk动态代理 还是cglib代理
if (Proxy.isProxyClass(beanClass)) {
// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
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);
}
}
// 如果使用了@DeclareParents,那么在添加advisor时,会把对应的接口添加到ProxyFactory中
// 在这一步会去判断advisors中是否存在IntroductionAdvisor,如果存在会把对应的Interface添加到ProxyFactory中
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// targetSource 里是包含目标对象的
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);
}
所以,我们可以理解@EnableAspectJAutoProxy,其实就是像Spring容器中添加了一个AbstractAdvisorAutoProxyCreator类型的Bean,从而开启了AOP,并且还会解析@Before等注解生成Advisor,AbstractAdvisorAutoProxyCreator会找到所有的Advisor,然后判断当前这个Bean是否存在某个Advisor与之匹配(根据Pointcut),如果匹配就表示当前这个Bean有对应的切面逻辑,需要进行AOP,需要产生一个代理对象。
未命名文件 | ProcessOn免费在线作图,在线流程图,在线思维导图 |
未命名文件 | ProcessOn免费在线作图,在线流程图,在线思维导图 |