Spring 在创建代理之前自动连接工作
Spring Autowired works before proxies are created
据我了解,Spring 在 postProcessBeforeInitialization
阶段使用 AutowiredAnnotationBeanPostProcessor
管理自动装配机制。但是它如何注入应该在 postProcessAfterInitialization
阶段创建的代理?
编辑 1
假设我有这个 Spring 配置
@Service
class RegularBean {
// injected on postProcessBeforeInitialization stage
@Autowired
private TransactionBean tBean;
// invoked in between of postProcessBeforeInitialization and postProcessAfterInitialization
@PostConstruct
void init() {
tBean.transactionMethod();
}
}
@Service
class TransactionBean {
// transactional proxy is created on postProcessAfterInitialization stage
@Transactional
public void transactionMethod() { ... }
}
事务代理在 postProcessAfterInitialization
阶段创建。但是 @PostConstruct
就在它之前被调用了。注入 tBean
是用交易代理包装的吗?如果是这样,那为什么呢?因为它不应该。如果不wrapped,那么以后的交易怎么处理?
假设我将字段注入替换为构造函数注入。它会以某种方式改变行为吗?
当您在方法或字段上使用自动装配时,Spring 容器并不总是创建和注入所需的 field/attribute 实例。 Spring 在内部创建智能代理并将代理注入您的 bean。这个智能代理将在稍后解析 bean,并在方法调用期间将调用委托给实际的 bean。这是我们使用 Scope 注释将请求和会话作用域 bean 解析为单例实例(比如服务层 bean)的常用策略。
添加小片段以显示 Spring 在内部为对象创建代理。当我们使用构造函数注入时,考虑一个经典的循环依赖案例。
@Component
public class CircularDependencyA {
private CircularDependencyB circB;
public CircularDependencyA(@Lazy CircularDependencyB circB) {
System.out.println("CircularDependencyA Ctr ->"+circB.getClass().getName());
this.circB = circB;
}
}
@Component
public class CircularDependencyB {
private CircularDependencyA circA;
public CircularDependencyB(CircularDependencyA circA) {
System.out.println("CircularDependencyB Ctr ->"+circA.getClass().getName());
this.circA = circA;
}
}
@Configuration
@ComponentScan(basePackages = { "com.example.springdemo.cd" })
public class TestConfig {
}
public class TestCircularDependency {
public static void main(String[] args) {
try(AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(TestConfig.class);){
}
}
}
根据我们的提示,Spring 正在为 CircularDependencyB 对象创建代理(使用 CGLIB)并查看 CircularDependencyA 构造函数中的操作
CircularDependencyA Ctr ->com.example.springdemo.cd.CircularDependencyB$$EnhancerBySpringCGLIB$$e6be3b79
谢谢
据我了解,Spring 在 postProcessBeforeInitialization
阶段使用 AutowiredAnnotationBeanPostProcessor
管理自动装配机制。但是它如何注入应该在 postProcessAfterInitialization
阶段创建的代理?
编辑 1
假设我有这个 Spring 配置
@Service
class RegularBean {
// injected on postProcessBeforeInitialization stage
@Autowired
private TransactionBean tBean;
// invoked in between of postProcessBeforeInitialization and postProcessAfterInitialization
@PostConstruct
void init() {
tBean.transactionMethod();
}
}
@Service
class TransactionBean {
// transactional proxy is created on postProcessAfterInitialization stage
@Transactional
public void transactionMethod() { ... }
}
事务代理在 postProcessAfterInitialization
阶段创建。但是 @PostConstruct
就在它之前被调用了。注入 tBean
是用交易代理包装的吗?如果是这样,那为什么呢?因为它不应该。如果不wrapped,那么以后的交易怎么处理?
假设我将字段注入替换为构造函数注入。它会以某种方式改变行为吗?
当您在方法或字段上使用自动装配时,Spring 容器并不总是创建和注入所需的 field/attribute 实例。 Spring 在内部创建智能代理并将代理注入您的 bean。这个智能代理将在稍后解析 bean,并在方法调用期间将调用委托给实际的 bean。这是我们使用 Scope 注释将请求和会话作用域 bean 解析为单例实例(比如服务层 bean)的常用策略。
添加小片段以显示 Spring 在内部为对象创建代理。当我们使用构造函数注入时,考虑一个经典的循环依赖案例。
@Component
public class CircularDependencyA {
private CircularDependencyB circB;
public CircularDependencyA(@Lazy CircularDependencyB circB) {
System.out.println("CircularDependencyA Ctr ->"+circB.getClass().getName());
this.circB = circB;
}
}
@Component
public class CircularDependencyB {
private CircularDependencyA circA;
public CircularDependencyB(CircularDependencyA circA) {
System.out.println("CircularDependencyB Ctr ->"+circA.getClass().getName());
this.circA = circA;
}
}
@Configuration
@ComponentScan(basePackages = { "com.example.springdemo.cd" })
public class TestConfig {
}
public class TestCircularDependency {
public static void main(String[] args) {
try(AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(TestConfig.class);){
}
}
}
根据我们的提示,Spring 正在为 CircularDependencyB 对象创建代理(使用 CGLIB)并查看 CircularDependencyA 构造函数中的操作 CircularDependencyA Ctr ->com.example.springdemo.cd.CircularDependencyB$$EnhancerBySpringCGLIB$$e6be3b79 谢谢