ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术
DefaultAopProxyFactory#createAopProxy
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快
// 或者isProxyTargetClass为true,
// 或者被代理对象没有实现接口,
// 或者只实现了SpringProxy这个接口
// 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理
// 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
// 是不是在GraalVM虚拟机上运行
if (!NativeDetector.inNativeImage() &&
// isOptimize:以前的cglib效率比较高 开启这个会选择cglib
// optimize为true,或proxyTargetClass为true,或用户没有给ProxyFactory对象添加interface
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
// targetClass是接口,直接使用Jdk动态代理
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.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快,或者isProxyTargetClass为true,或者被代理对象没有实现接口,
或者只实现了SpringProxy这个接口, 那么则利用Cglib进行动态代理,
但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理
其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口
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");
}
this.advised = config;
// 设置JDK动态代理所要代理的接口
this.proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(this.proxiedInterfaces);
}
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
// 被代理对象自己所实现的接口
Class<?>[] specifiedInterfaces = advised.getProxiedInterfaces();
// 如果被代理对象没有实现接口,则判断被代理类是不是接口,或者被代理类是不是已经经过JDK动态代理之后的类从而获取想对应的接口
if (specifiedInterfaces.length == 0) {
// No user-specified interfaces: check whether target class is an interface.
Class<?> targetClass = advised.getTargetClass();
if (targetClass != null) {
if (targetClass.isInterface()) {
advised.setInterfaces(targetClass);
}
else if (Proxy.isProxyClass(targetClass)) {
advised.setInterfaces(targetClass.getInterfaces());
}
specifiedInterfaces = advised.getProxiedInterfaces();
}
}
// 添加三个Spring内置接口:SpringProxy、Advised、DecoratingProxy
List<Class<?>> proxiedInterfaces = new ArrayList<>(specifiedInterfaces.length + 3);
for (Class<?> ifc : specifiedInterfaces) {
// Only non-sealed interfaces are actually eligible for JDK proxying (on JDK 17)
if (isSealedMethod == null || Boolean.FALSE.equals(ReflectionUtils.invokeMethod(isSealedMethod, ifc))) {
proxiedInterfaces.add(ifc);
}
}
if (!advised.isInterfaceProxied(SpringProxy.class)) {
proxiedInterfaces.add(SpringProxy.class);
}
if (!advised.isOpaque() && !advised.isInterfaceProxied(Advised.class)) {
proxiedInterfaces.add(Advised.class);
}
if (decoratingProxy && !advised.isInterfaceProxied(DecoratingProxy.class)) {
proxiedInterfaces.add(DecoratingProxy.class);
}
return ClassUtils.toClassArray(proxiedInterfaces);
}
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)
,得到代理对象,dkDynamicAopProxy作为InvocationHandler,代理对象在执行某个方法时,会进入到JdkDynamicAopProxy的invoke方法中DefaultAdvisorAutoProxyCreator的父类是AbstractAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator非常强大以及重要,只要Spring容器中存在这个类型的Bean,就相当于开启了AOP
AbstractAdvisorAutoProxyCreator实际上就是一个BeanPostProcessor,所以在创建某个Bean时,就会进入到它对应的生命周期方法中,比如:在某个Bean初始化之后,会调用wrapIfNecessary()方法进行AOP.
底层逻辑是:
AbstractAdvisorAutoProxyCreator会找到所有的Advisor,然后判断当前这个Bean是否存在某个Advisor与之匹配(根据Pointcut),
如果匹配就表示当前这个Bean有对应的切面逻辑,需要进行AOP,需要产生一个代理对象。
这个注解主要就是往Spring容器中添加了一个AnnotationAwareAspectJAutoProxyCreator类型的Bean
AspectJAwareAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator,重写了findCandidateAdvisors()方法,AbstractAdvisorAutoProxyCreator只能找到所有Advisor类型的Bean对象,但是AspectJAwareAdvisorAutoProxyCreator除开可以找到所有Advisor类型的Bean对象,还能把@Aspect注解所标注的Bean中的@Before等注解及方法进行解析,并生成对应的Advisor对象
所以,我们可以理解@EnableAspectJAutoProxy,其实就是像Spring容器中添加了一个AbstractAdvisorAutoProxyCreator类型的Bean,从而开启了AOP,并且还会解析@Before等注解生成Advisor
详细链接: https://www.processon.com/view/link/62643a4a1efad452156b8a2e