【问题标题】:Spring-Boot @Autowired variable is nullSpring-Boot @Autowired 变量为空
【发布时间】:2020-10-11 19:16:03
【问题描述】:

我正在尝试使用 Spring-boot 类中的 @Autowired 注释将存储库放入使用 @Service 注释的类中。但是,存储库显示为空。

以下是相关代码:

@Service
public class ImportLicenses {


    @Autowired
    private LicenseRepository licenseRepository;

   public static void main (String[] args) {
            ImportLicenses importLicenses = new ImportLicenses();
            importLicenses.listFiles("/Users/admin/Licenses/licenses");
    }



  private void processLicense (Path path) {


        try {
            count++;
            BasicFileAttributes attr = Files.readAttributes(path, BasicFileAttributes.class);
            FileTime fileTime = attr.lastModifiedTime();

            Permission permission = new Permission(readLineByLineJava8(path.toFile().getAbsolutePath()));

            LicensePojo licensePojo = new LicensePojo(permission, path);


            Optional<License> licenseOptional = licenseRepository.findById(licensePojo.getId());

此时它会获得 NPE,因为 licenceReposity 为空。

我可以使用这个构造函数访问控制器类中的 licenseRepository

public LicenseController(LicenseRepository licenseRepository,
                         UserRepository userRepository) {
    this.licenseRepository = licenseRepository;
    this.userRepository = userRepository;
}

但是,由于我是在静态 main 方法中直接调用构造函数,所以这似乎不可用。将存储库放入此类的最佳方法是什么?

编辑:感谢您的回复。为了澄清这个问题,我试图将这个类拉入现有 Spring Boot 应用程序的结构中,而不是创建一个单独的。

选项 1:在 UI 上创建一个按钮或菜单选择,并创建一个新的控制器类来运行导入。这将是最简单的,但我不想在 UI 上一定要有它。

选项 2:编写导入类创建另一个 Spring 应用程序

@SpringBootApplication
public class ImportLicenses implements ApplicationRunner {

    private final Logger logger = LoggerFactory.getLogger(LicenseGenApplication.class);

    @SpringBootApplication
    public static void main() {
        main();
    }


    public static void main(String[] args) {

        SpringApplication.run(ImportLiceneses.class, args);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
 
        listFiles("/Users/admin//licenses");

    }

    public void listFiles(String path) {

        try {
            Files.walk(Paths.get(path))
                    .filter(ImportLicenses::test)
                    .forEach(p -> processLicense(p));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    ....

}

选项 3 - 从现有应用程序创建一个不可执行的 jar 文件以用于新应用程序,以避免重复代码。

选项1最快,不知道选项2是否可行,选项3我看看是否可行。

【问题讨论】:

  • 您没有安装 Spring Boot,您应该使用一些初学者:start.spring.io
  • @Sotirios Delimanolis:你提到的问题有完全不同的原因。它描述了在没有 Spring 的情况下创建实例的情况。但它是一个 Spring 应用程序,目标 bean 由 Spring 管理。在这种情况下,根本没有使用 Spring,甚至没有初始化 Spring。这种情况绝对是不是重复的
  • 这是一个 Spring Boot 应用程序,正如我在 LicenseController 条目中所引用的那样。我将进行编辑以使其更加明显。问题是我正在尝试运行一个单独的类来导入数据,并且不希望从中创建一个单独的应用程序。
  • 你没有抓住重点。如果您自己初始化对象,则显然不涉及 Spring,无论其余对象是否“在 Spring 的上下文中运行”。它非常重复。您没有使用 Spring 来创建您的实例。答案是使用 Spring 创建实例,如果您想要 Spring 适当地注入 bean。
  • @JackBeNimble:您展示的ImportLicenses不是 Spring 应用程序。

标签: java spring-boot dependency-injection repository autowired


【解决方案1】:

您的应用程序是一个普通的 Java 应用程序。它不是 Spring Boot 应用程序。

你应该怎么做?制作一个 Spring Boot 应用程序。例如,在https://start.spring.io/ 创建一个演示应用程序,将您的主类与演示应用程序中的主类进行比较,然后相应地调整您的主类。还将您的 Maven 或 Gradle 配置与演示应用程序的配置进行比较并进行相应调整。

至少,你的应用程序应该有一个注解@SpringBootApplication。此外,它应该通过SpringApplication.run(...) 启动。这是最低要求。根据您的需要,您可能需要使用@EnableAutoConfiguration 和其他配置选项。

【讨论】:

  • 感谢您的回答。我将为此提供一个 GUI 链接。这是一次性的,所以我真的不需要为它创建一个完整的单独应用程序。这是一种实用功能,对于一个更完善的应用程序,我可能会拥有和管理部分,所以无论如何它都属于 GUI。
  • 如果不初始化 Spring 上下文,就无法初始化 Spring bean。它不必是整个 Spring 应用程序。您可以创建一个替代的“轻”上下文。但无论如何你都需要初始化 Spring 上下文。
猜你喜欢
  • 2017-10-29
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-14
  • 2015-09-14
  • 2022-08-19
  • 2017-12-06
  • 2014-12-15
相关资源
最近更新 更多