据我所知,spring提供了一些将bean注入(inject)非托管类的方法。 可以使用 AutowireCapableBeanFactory 显式完成。 (How to inject dependencies into a self-instantiated object in Spring?)
但是当 spring 自动执行此类注入(inject)时,我遇到了奇怪的(恕我直言)行为。
这是一个 Spring Batch 的示例,
配置:
@SpringBootConfiguration
public class ProcessorJobConfig {
//.....
@Bean(name = "pullRestTemplate")
public RestTemplate createPullRestTemplate() {
RestTemplate restTemplate = restTemplateBuilder.build();
return restTemplate;
}
@Bean(name = "step")
public Step step(@Autowired ItemReader<Measurement> itemReader,
@Autowired ItemProcessor<Measurement, Event> itemProcessor,
@Autowired ItemWriter<Event> itemWriter) {
return stepBuilderFactory.get("step")
.<Measurement, Event>chunk(Integer.MAX_VALUE)
.reader(itemReader)
.processor(itemProcessor)
.writer(itemWriter)
.build();
}
@Bean(name = "restProcessorJob")
public Job job(@Qualifier("step") Step step) throws Exception {
return jobBuilderFactory.get("restProcessorJob")
.start(step)
.build();
}
@Bean
public ItemReader<Measurement> itemReader() {
RestMeasureReader restMeasureReader = new RestMeasureReader(); // Use new() explicitly
return restMeasureReader;
}
//.....
}
读者:
public class RestMeasureReader implements ItemReader<Measurement> {
private static final Logger LOGGER = LoggerFactory.getLogger(RestMeasureReader.class);
/**
* NOTE: This field will be injected automatically by spring, even we are using new() to create instance of this class.
*/
@Autowired
@Qualifier("pullRestTemplate")
private RestTemplate restTemplate;
@Override
public Measurement read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
// do some stuff
}
}
以及应用程序本身
@EnableBatchProcessing
@EnableTask
@SpringBootApplication
public class TestAutowiredTaskApplication {
public static void main(String[] args) {
SpringApplication.run(TestAutowiredTaskApplication.class, args);
}
}
即使我使用显式 new() 来实例化 RestMeasureReader,其 RestTemplate 字段也会在之后注入(inject)。 这是正常行为吗?我不希望 spring 在使用 new() 创建对象时自动注入(inject)字段。
最佳答案
如果您正在讨论在 @Configuration
类中使用 new
,那么是的,这是正常行为。这是 Spring java 配置。所以它是 Spring 管理的上下文。您不会在代码中显式调用 itemReader()
。
因此,当您要执行此操作时:
@Autowired
private ItemReader<Measurement> iterReader;
您将从 Spring 的 IoC 获取 RestMeasureReader
实例。
但是,如果您尝试在代码中显式调用 new RestMesureReader()
,您将获得 RestMesureReader
的新实例,而不是注入(inject)了 @Autowired
字段。
尝试从 itemReader()
方法声明中删除 @Bean
,并且事件无法 Autowiring RestMesureReader
。
所以基本上@Configuration
类只是一个Spring配置,而不是真正的java代码。即使您调用 new
Spring 仍会返回一个代理类。
欲了解更多信息,请查看this guide .
关于java - 为什么非托管类中会自动弹出 @Autowitred 字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41381345/