As far as I know spring provides some ways to inject beans into non-managed classes. It can be done explicitly with AutowireCapableBeanFactory. (How to inject dependencies into a self-instantiated object in Spring?)
But I've faced strange (IMHO) behavior, when spring performs such injection automatically.
Here is an example with spring batch,
Configuration:
@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;
}
//.....
}
Reader:
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
}
}
And application itself
@EnableBatchProcessing
@EnableTask
@SpringBootApplication
public class TestAutowiredTaskApplication {
public static void main(String[] args) {
SpringApplication.run(TestAutowiredTaskApplication.class, args);
}
}
Even I use explicit new() to instantiate RestMeasureReader, its RestTemplate field will be injected afterwards. Is it normal behavior? I do not expect spring to automatically inject fields when creating object with new().