概述
Spring 动态代理两种实现:JDK 动态代理,CGLIB 动态代理
Spring默认使用JDK的动态代理实现AOP,类如果实现了接口,Spring就会使用这种方式实现动态代理;否则使用 CGLIB 实现
JDK 动态代理是通过实现 InvocationHandler 接口,重写 invoke,然后通过 Proxy.newProxyInstance 返回代理对象
CGLib直接操作字节码,生成类的子类,重写类的方法完成代理。注意,CGLIB 不能代理被 final 修饰的方法,因为 final 是不可变不可继承。
样例
JDK 动态代理
// 接口
public interface ITestA {
void sayHello();
}
// 实现类
@Component
public class TestA implements ITestA {
@Override
public void sayHello() {
System.out.println("Hello A");
}
}
// 切面
@Aspect
@Component
public class AspectA {
@Before(value = "execution(* com.example.springaop.service.TestA.*(..))")
public void before(){
System.out.println("Before hello");
}
}
// 单元测试
@SpringBootTest
class SpringAopApplicationTests {
@Autowired
private ITestA iTestA;
@Test
void contextLoads() {
iTestA.sayHello();
System.out.println(iTestA.getClass().getSuperclass());
}
}
若使用 Spring Boot 2.5.2 版本,application.properties 配置文件需开启一下配置spring.aop.proxy-target-class=false
,否则会默认使用 CGLIB。
输出:
Before hello
Hello A
class java.lang.reflect.Proxy
CGLIB 动态代理
// 没有实现接口
@Component
public class TestB {
public void sayHello(){
System.out.println("Hello B");
}
}
@Aspect
@Component
public class AspectB {
@Before(value = "execution(* com.example.springaop.cblib.TestB.*(..))")
public void before(){
System.out.println("befor B Hello");
}
}
@SpringBootTest
class SpringAopApplicationTests {
@Test
void testB(){
testB.sayHello();
System.out.println(testB.getClass());
}
}
输出
befor B Hello
Hello B
class com.example.springaop.cblib.TestB$$EnhancerBySpringCGLIB$$3914f3c1
代理对象创建源码分析
从 Bean 的生命周期可以知道,Bean 在初始化阶段会执行 BeanPostProcessor 扩展点实现,直接从这里开始学习。
- BeanPostProcessor.postProcessAfterInitialization 执行 AOP 增强
public abstract class AbstractAutowireCapableBeanFactory {
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
if (mbd == null || !mbd.isSynthetic()) {
// 执行后置拓展点
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
// 执行 BeanPostProcessor 拓展点后置方法
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
BeanPostProcessor processor = (BeanPostProcessor)var4.next();
current = processor.postProcessAfterInitialization(result, beanName);
}
return result;
}
}
- AbstractAutoProxyCreator 重写 postProcessAfterInitialization 方法,通过 ProxyFactory.getProxy 方法得到代理对象。
public abstract class AbstractAutoProxyCreator {
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 返回代理
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
return proxyFactory.getProxy(classLoader);
}
}
- ProxyFactory.getProxy 会先调用 ProxyCreatorSupport.getAopProxyFactory 创建工厂,然后再调用 createAopProxy 方法创建代理。
public class ProxyFactory extends ProxyCreatorSupport {
public Object getProxy(@Nullable ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
}
public class ProxyCreatorSupport extends AdvisedSupport {
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
this.activate();
}
return this.getAopProxyFactory().createAopProxy(this);
}
}
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//
if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
// 如果不是接口 && 不是代理类,那么走 ObjenesisCglibAopProxy,否则走 JdkDynamicAopProxy
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
}
}