Estou olhando os exemplos do spring-batch e estou surpreso ao ver um método construtor de bean sendo chamado diretamente, em vez de por meio de uma referência de bean. Estou me perguntando se isso é um erro.
...
@Configuration
@EnableBatchProcessing
public class SpringBatchConfig {
...
@Bean
public FlatFileItemReader<User> itemReader() {
FlatFileItemReader<User> flatFileItemReader = new FlatFileItemReader<>();
...
flatFileItemReader.setLineMapper(lineMapper());
return flatFileItemReader;
}
@Bean
public LineMapper<User> lineMapper() {
...
}
Enquanto o método construtor do bean lineMapper()
é anotado como @Bean
, o método construtor do bean itemReader()
não injeta o bean em seu construtor, mas sim o chama lineMethod()
diretamente.
Eu esperava esta definição de itemReader()
:
@Bean
public FlatFileItemReader<User> itemReader(LineMapper<User> lineMapper) {
FlatFileItemReader<User> flatFileItemReader = new FlatFileItemReader<>();
...
flatFileItemReader.setLineMapper(lineMapper);
return flatFileItemReader;
}
Isso não é um erro nas amostras atuais do spring-batch? Ou eu estou esquecendo de alguma coisa? Talvez @Configuration
faça algo mágico e converta chamadas diretas para construtores em um bean com proxy? Talvez lineMapper()
nem precise ser um feijão?
Obrigado por qualquer visão.
Ambas as formas que você mencionou terão o mesmo efeito que injetará o
LineMapper
bean no métodoFlatFileItemReader
'@bean
.Para o
SpringBatchConfig
caso, está usando o recurso de injeção de dependências entre bean , que permite injetar um bean em um@Bean
método por meio de chamada direta de método. E seu palpite está correto, funciona porque o@Bean
método é proxy doConfigurationClassEnhancer.BeanMethodInterceptor
se você estiver interessado em saber como funciona no nível do código.Observe que este recurso só será habilitado se você estiver usando o modo full bean (ou seja, o método Then
@Bean
é definido dentro da@Configuration
classe) e@Configuration
'sproxyBeanMethods=true
(valor padrão).Caso contrário, qualquer uma das situações a seguir fará com que a chamada
lineMapper()
apenas crie uma nova instância, mas não acesse aLineMapper
instância a partir do contexto spring:proxyBeanMethods=false
: