Spring AOP源码解析:生成代理对象

Spring AOP源码解析:生成代理对象_第1张图片

生成代理对象

上一节我们分享了获取bean对应的切面(advice)的过程,本节我们接着分享生成代理对象的过程

AbstractAutoProxyCreator#wrapIfNecessary
Spring AOP源码解析:生成代理对象_第2张图片
刚开始的3个if条件是直接跳过不需要代理的bean,例如用户自定义的targetSource,spring aop的基础类等。

getAdvicesAndAdvisorsForBean是获取应用在当前Bean上面的切面,如果没有的话就不用进行代理了

在生成代理的时候,并不是对原始的Bean直接生成代理对象,而是将Bean包装为TargetSource,然后对TargetSource生成代理对象。

为什么中间加一道呢?
这样我们就可以利用TargetSource对被代理的类做一些操作,例如池化,热部署等

在这里插入图片描述
AbstractAutoProxyCreator#createProxy
Spring AOP源码解析:生成代理对象_第3张图片

ProxyFactory#getProxy
在这里插入图片描述
Spring AOP源码解析:生成代理对象_第4张图片
用工厂模式来创建AopProxy,工厂的实现类只有一个DefaultAopProxyFactory
Spring AOP源码解析:生成代理对象_第5张图片
config.isOptimize:控制通过cglib创建的代理是否使用激进的优化策略,默认是false,一般也不会改变

config.isProxyTargetClass:是否使用cglib来创建代理对象,默认是false

// 可以通过如下方式设置为true
@EnableAspectJAutoProxy(proxyTargetClass = true)

hasNoUserSuppliedProxyInterfaces:代理类是否实现了接口

所以一般情况下代理类实现了接口,则使用jdk动态代理,否则使用cglib代理
可以通过设置@EnableAspectJAutoProxy(proxyTargetClass = true)统一使用cglib代理。

使用cglib代理的时候,当代理对象是个接口,或者是代理对象是jdk动态代理对象时,依旧会使用jdk动态代理

举个例子,当我们对EchoService进行动态代理时,虽然配置了@EnableAspectJAutoProxy(proxyTargetClass = true)来使用cglib进行代理,但因为被代理是jdk动态代理对象,因此还是会使用jdk动态代理

@Bean
public EchoService echoService() {
    return (EchoService) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{EchoService.class}, new EchoProxy());
}

参考博客

[1]https://blog.csdn.net/choubayan4320/article/details/100868024
[2]https://www.cnblogs.com/lifullmoon/p/14684886.html

你可能感兴趣的:(Spring,spring,java,后端)