java - 为什么非托管类中会自动弹出 @Autowitred 字段

标签 java spring spring-boot dependency-injection autowired

据我所知,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/

相关文章:

spring - 向 MappingJacksonHttpMessageConverter 添加新媒体类型

java - 在 Web 应用程序中更新 mysql

java - Geotools lib 突然从存储库中消失

Spring 启动: Thymeleaf not resolving fragments after packaging

spring - Visual Studio代码+ Spring Boot项目更改spring.properties.additional-location等

ajax - Spring Boot - 外部 Tomcat 服务器 Ajax 身份验证失败消息

java - 如何在spring sts中获取spring boot web项目的默认结构?

java - Hibernate DiscriminatorColumn.Type 不工作

java - 键盘中断布局和行为

java - 选项出现在 JMenu 上