Spring AOP 代理分析

2023-12-20  本文已影响0人  Tinyspot

1. Spring AOP 代理

1.1 代理时机

1.2 代理创建

Bean后置处理器 BeanPostProcessor
postProcessBeforeInstantiation() 可在 Spring 实例化 Bean 对象之前,创建一个 Bean
postProcessBeforeInitialization() 可在 Bean 的初始化方法被执行前,修改 Bean
postProcessAfterInitialization() 可在 Bean 的初始化方法被执行前,修改 Bean

实现类 AbstractAutoProxyCreator

方法postProcessAfterInitialization() 在 Bean 初始化后调用

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

wrapIfNecessary() 创建 ProxyFactory 工厂

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // ...
    Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    // ...
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    // ...
    ProxyFactory proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
    // ...
}

ProxyFactory 的无参构造方法里没有逻辑

public class ProxyFactory extends ProxyCreatorSupport {
    public ProxyFactory() {
    }
}

父类 ProxyCreatorSupport 的无参构造如下:

public class ProxyCreatorSupport extends AdvisedSupport {
    private AopProxyFactory aopProxyFactory;

    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }
}

继续顺着继承关系往上找,父类 AdvisedSupport 的无参构造如下:

public class AdvisedSupport extends ProxyConfig implements Advised {
    public AdvisedSupport() {
        this.methodCache = new ConcurrentHashMap<>(32);
    }
}

2. Spring Boot 自动配置类 AopAutoConfiguration

Spring 需要手动添加 @EnableAspectJAutoProxy 注解进行集成
SpringBoot 可自动装配 spring-boot-autoconfigure.jar/META-INF/spring.factories

package org.springframework.boot.autoconfigure.aop;

@AutoConfiguration
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(Advice.class)
    static class AspectJAutoProxyingConfiguration {

        @Configuration(proxyBeanMethods = false)
        @EnableAspectJAutoProxy(proxyTargetClass = false)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
        static class JdkDynamicAutoProxyConfiguration {

        }

        @Configuration(proxyBeanMethods = false)
        @EnableAspectJAutoProxy(proxyTargetClass = true)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
                matchIfMissing = true)
        static class CglibAutoProxyConfiguration {

        }

    }
}

参考

上一篇 下一篇

猜你喜欢

热点阅读