Spring Autowired 在创建代理之前工作

Sem*_*kov 6 spring dependency-injection spring-mvc spring-aop

据我了解,SpringAutowiredAnnotationBeanPostProcessorpostProcessBeforeInitialization舞台上管理自动装配机制。但它如何注入应该在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() { ... }
}
Run Code Online (Sandbox Code Playgroud)

事务代理是在postProcessAfterInitialization舞台上创建的。但@PostConstruct在它之前被调用。注入是否tBean包含事务代理?如果是这样,那为什么呢?因为不应该这样。如果不包装,那么以后的交易将如何处理?

假设我用构造函数注入替换字段注入。它会以某种方式改变行为吗?

Pau*_*ric 3

当您在方法或字段上使用自动装配时,Spring 容器并不总是创建并注入所需的字段/属性实例。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);){
            
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

根据我们的提示,Spring 正在为 CircularDependencyB 对象创建代理(使用 CGLIB),并从 CircularDependencyA 构造函数 CircularDependencyA Ctr ->com.example.springdemo.cd.CircularDependencyB$$EnhancerBySpringCGLIB$$e6be3b79 查看操作