简体   繁体   中英

Spring bean not being picked up?

I have a java spring project with the below service:

@Slf4j
public class DialogFlowService {

    private String projectId;
    private String sessionId;
    private String languageCode;

    public DialogFlowService(DialogFlowConfig dialogFlowConfig) {
        log.info("aaa" + dialogFlowConfig.languageCode);
        this.projectId = dialogFlowConfig.projectId;
        this.sessionId = dialogFlowConfig.sessionId;
        this.languageCode = dialogFlowConfig.languageCode;
    }
}

The constructor takes the below class as an argument:

@Configuration
@ConfigurationProperties(prefix = "dialog-flow")
public class DialogFlowConfig {

    @NotNull
    public String projectId;

    @NotNull
    public String sessionId;

    @NotNull
    public String languageCode;
}

In theory, this should be instantiated by the below bean:

@Bean
public DialogFlowService dialogFlowService() {
   return new DialogFlowService(new DialogFlowConfig());
}

However in practice, when I try to log one of the constructor arguments, it comes up as null. Am I missing something?

I think changing your third code snippet like this would do the trick.

@Bean
public DialogFlowService dialogFlowService(DialogFlowConfig  dialogFlowConfig) {
    return new DialogFlowService(dialogFlowConfig);
}

The DialogFlowConfig class is already marked as @Configuration . Hence it is managed by the Spring Application context. So you dont have to explicitly make an object using the new keyword. You can just take it as a parameter

Try putting @EnableConfigurationProperties(DialogFlowConfig.class) into you Spring Application class.

This is similar to what's being described here: Why is my Spring @Autowired field null?

Essentially, by instantiating the DialogFlowConfig instance yourself and not handing it over to Spring, you're preventing Spring from post processing it and injecting ConfigurationProperties property values.

Instead create a @Bean method for DialogFlowConfig and use the corresponding Spring bean to create your DialogFlowService . For example

@Bean
public DialogFlowService dialogFlowService(DialogFlowConfig dialogFlowConfig) {
    return new DialogFlowService(dialogFlowConfig);
}

@Bean
public DialogFlowConfig dialogFlowConfig() {
    return new DialogFlowConfig();
}

Spring will use the @Bean annotated dialogFlowConfig() factory bean method to instantiate and process the corresponding instance (setting its fields). It'll then use it with the dialogFlowService() factory method.

Note: If you do it this way, you'll need to remove @Configuration annotation from DialogFlowConfig , assuming you were previously component scanning it. Alternatively, if you were correctly component scanning, you don't even need the additional @Bean annotated dialogFlowConfig() factory method I proposed. Just inject the DialogFlowConfig bean declared by its @Configuration annotation in the dialogFlowService method.

First of all you need to use either setter getter in DialogFlowConfig or @Value annotation on all properties. You also need to annotate your service class DialogFlowService with @Service stereotype

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM