Игнорировать обработку полей @Value зависимых библиотек из Spring Bean Post Processor - PullRequest
2 голосов
/ 03 октября 2019

Я использую один из наших проектов как зависимость в другом. Один из классов в зависимом проекте выглядит следующим образом:

@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");
  }
}

Tryingчтобы получить доступ к dependencyBean, созданному следующим образом

public class SomeClass {

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

}

Я получаю следующее исключение

BeanCreationException: Ошибка при создании bean-компонента с именем 'absoluteBean': сбой внедрения зависимостей с автопроводкой;Вложенное исключение: org.springframework.beans.factory.BeanCreationException: Не удалось автоматически связать поле: private java.lang.String xyz;

Как создать экземпляр зависимого класса без вызова postProcessPropertyValues, которыйпытается разрешить поля с пометкой @Value?

1 Ответ

0 голосов
/ 04 октября 2019

Во-первых, вам нужно включить переопределение bean-компонентов с помощью;

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

и просто иметь свой собственный bean-компонент с точным именем в качестве @Service аннотированного класса;

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

Таким образом, вы можете переопределить аннотированный @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 autowired.

...