Spring AOP 代理分析
2023-12-20 本文已影响0人
Tinyspot
1. Spring AOP 代理
1.1 代理时机
- Spring 使用模板模式,在 Bean 的创建过程中安插了许多锚点,用户寻找对应的锚点,通过重写方法介入到 Bean 的创建过程当中
- 介入 Spring Ioc 创建 Bean 的过程,最好的方式就是实现 BeanPostProcessor
1.2 代理创建
Bean后置处理器 BeanPostProcessor
postProcessBeforeInstantiation()
可在 Spring 实例化 Bean 对象之前,创建一个 Bean
postProcessBeforeInitialization()
可在 Bean 的初始化方法被执行前,修改 Bean
postProcessAfterInitialization()
可在 Bean 的初始化方法被执行前,修改 Bean
![](https://img.haomeiwen.com/i20154612/8a47f7c31082745f.png)
实现类 AbstractAutoProxyCreator
![](https://img.haomeiwen.com/i20154612/7a7f31d8b8754410.png)
方法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);
// ...
}
![](https://img.haomeiwen.com/i20154612/d5307b5e228ae838.png)
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);
}
}
![](https://img.haomeiwen.com/i20154612/03ac0a09880291d8.png)
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 {
}
}
}
参考
- Spring 源码阅读 48:用于创建 AOP 代理的后处理器分析
- Spring 源码阅读 56:创建 ProxyFactory