忽略来自 Spring Bean Post Processor 的依赖库的 @Value 字段处理

Ignore @Value field processing of dependent libraries from Spring Bean Post Processor

我正在使用我们的一个项目作为另一个项目的依赖项。依赖项目中的classes之一如下:

@Service
public class Dependency {

  @Value("${xyz.value}")
  private String xyz;

  @Value("${abc.value}")
  private String abc;

  public Dependency() {

  }

  public Dependency(String xyz, String abc) {
    this.xyz = xyz;
    this.abc = abc;
  }
}

我正在尝试在启动时在另一个项目中创建 Dependency 的实例,如下所示:

@Configuration
@PropertySource(value = {
    "classpath:appEnv.properties"
}, ignoreResourceNotFound = true)

public class Test {

  @Bean(name = "dependencyBean")
  public Dependent getDependent() {
    return new Dependent("xyz", "abc");
  }
}

正在尝试访问如下创建的dependencyBean

public class SomeClass {

  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
  Dependent d = ctx.getBean("dependencyBean"); 

}

我收到以下异常

BeanCreationException: Error creating bean with name 'dependentBean': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private java.lang.String xyz;

如何在不调用 postProcessPropertyValues 的情况下创建 Dependent class 的实例,后者试图使用 @Value 注释解析字段?

您首先需要启用 bean 覆盖;

spring.main.allow-bean-definition-overriding=true

并且让您的自定义 bean 具有与 @Service 注释 class;

完全相同的名称
@Bean(name = "dependency")
public Dependency getDependent() {
    return new Dependency("xyz", "abc");
}

因此,您可以使用手动初始化的 bean 覆盖 @Service 注释的 Dependency。但要实现这一点,您首先必须禁止您的自定义 getDependent() 结果 bean 触发 @Value 注释,为此,您需要更改 Dependency class @Value 构造函数的注入方法。这样的话,只有Spring自动注入时,@Value注解才会触发,手动调用new Dependency("xyz", "abc")时不会触发。

@Service
public class Dependency {

    private String xyz;
    private String abc;

    @Autowired
    public Dependency(@Value("${xyz.value}") String xyz, @Value("${abc.value}") String abc) {
        this.xyz = xyz;
        this.abc = abc;
    }
}

进行这些更改后,您的自定义 bean 将不会出现错误。