Spring Application拒绝自动装配(配置为空)

时间:2019-04-14 06:21:27

标签: java spring spring-boot

我已经看到所有关于弹簧自动接线配置为空的问题,而且我似乎无法弄清楚。因此,我将其简化为一个小问题,希望有人能提供帮助。

Spring应用程序 Hello.java

package hello;

@SpringBootApplication
public class Hello {
  private static final Logger log = LoggerFactory.getLogger(Hello.class);

  @Autowired
  private AppConfig appConfig;

  public void start() {
    log.info("Start");
    log.info("AppConfig: {}", appConfig);
  }

  public static void main(String args[]) {
    SpringApplication.run(Hello.class, args).close();
  }

  @Bean
  public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
      Hello hello = new Hello();
      hello.start();
    };
  }
}

AppConfig.java

package hello;

@Configuration
public class AppConfig {

  @Value("${string.test:bob}")
  private String commandLineArg;

  public String getCommandLineArg() {
    return commandLineArg;
  }
}

运行此功能!但是,它将null变量记录在appConfig中。从我的角度来看,它应该已经自动实例化并填写了。这是怎么回事?

3 个答案:

答案 0 :(得分:1)

在您的commandLineRunner中,您自己实例化了“ Hello”(新的Hello()),因此您的“ hello”对象在Spring之前不是托管Bean,因此它根本没有依赖项注入。

您这样做有什么特殊原因吗? Spring将通过@ SpringBootApplication-Annotation实例化Hello。在您的CommandLineRunner中,只需调用“ start()”,即可自动关联您的依赖项:

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
        start();
    };
}

如果CommandLineRunner正在从另一个类运行,则可以通过以下方式获取Spring管理的“ Hello”实例:

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> {
        Hello foo = ctx.getBean(Hello.class);
        foo.start();
    };
}

答案 1 :(得分:1)

Hello hello = new Hello(); // Creates new Hello instance, not managed by Spring container

改为使用:

package com.example.demo;

import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

}

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {

    @Autowired
    AppConfig appConfig;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);

    }

    public void start() {
        System.out.println("Start");
        System.out.println("AppConfig: {}" + appConfig);
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {
            this.start();
        };
    }
}

输出:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.4.RELEASE)

2019-04-14 12:22:49.515  INFO 7892 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on sparrow with PID 7892 (/home/anant/Downloads/demo/target/classes started by anant in /home/anant/Downloads/demo)
2019-04-14 12:22:49.519  INFO 7892 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2019-04-14 12:22:50.446  INFO 7892 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.383 seconds (JVM running for 1.875)
Start
AppConfig: {}com.example.demo.AppConfig$$EnhancerBySpringCGLIB$$9ca35f67@68f1b17f

答案 2 :(得分:1)

在CommandLineRunner bean中,您正在创建Hello的新实例,并在其上调用start。您好实例不是Spring bean,因此自然不会注入任何依赖项。要使其正常工作,只需在您的CommandLineRunner bean中调用start(),CommandLineRunner在应用程序上下文填充并准备就绪后运行:

@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
    return args -> start();
}

或者,您可以在start()方法上添加@PostConstruct以便在Spring应用程序上下文中填充bean之后运行:

    @PostConstruct
    public void start() {
        log.info("Start");
        log.info("AppConfig: {}", appConfig);
    }