【问题标题】:How to scan packages which are not in src/main/java?如何扫描不在 src/main/java 中的包?
【发布时间】:2019-10-23 06:00:11
【问题描述】:

面试官问,你将如何扫描不在 src/main/java .. 即.. 你的类路径中的包。 他还说,当你必须做这种事情时,这种情况非常罕见。

【问题讨论】:

标签: java spring maven spring-boot spring-tool-suite


【解决方案1】:

在 spring-boot 中,默认情况下,主应用程序类所在的包下的所有类都是组件扫描的。例如,假设您的主要application.javasrc/main/java 下,在包com.example 中。所以springboot会扫描com.example.*包下的所有类所以如果你的其他包层次结构在你的主应用程序下面并带有@SpringBootApplication注解,你就会被隐式组件扫描所覆盖。 如果其他包中有bean/组件不是主包的子包,则应手动将它们添加为@ComponentScan,如:

@ComponentScan({“com.example1”,”com.example2”})
@SpringBootApplication
public class SpringbootMainApplication {
public static void main(String[] args) {
        ApplicationContext applicationContext = 
                SpringApplication.run(SpringbootMainApplication.class, args);
    }

}

除此之外,@ComponentScan 注释还可以与 @Configuration 注释类一起提供,以告诉 spring 扫描包。 @ComponentScan 不带参数告诉 Spring 扫描当前包及其所有子包。Like :

@Configuration
@ComponentScan
public class SpringGenericConfiguration {
    @Bean
    public ExampleBean exampleBean() {
     return new ExampleBean();
    }
}

假设 SpringGenericConfiguration.java 类在包 com.example20.configuration 中,那么 spring 将扫描包中的所有类以及子包中的所有类。

【讨论】:

  • 我认为上面的代码会将包中指定的所有组件添加到src/main/java下。我相信 OP 要求提供在 src/main/java 以外的路径中包含代码的方法
  • @KavithaKarunakaran 像 maven 和 gradle 这样的构建工具需要我们遵循一个基本的目录结构。按照惯例,所有java代码通常都放在src/main/java下。如果构建工具正确编译了类并找到了进入jar或war的方式,那么只有在spring启动时组件扫描注释才能工作。
  • 我同意你说的。但是,如果您需要在运行生成的源目标时在运行时创建一些存根,则需要将它们添加到类路径中,然后只有它才能工作。
  • @KavithaKarunakaran 看来我们对手头的问题有不同的理解:)
  • 如果添加@SpringBootApplication,那么最好不要添加@ComponentScan,而是将参数scanBasePackages添加到@SpringBootApplication
【解决方案2】:

我认为您需要先将文件夹手动添加到您的 java 构建路径中,然后再将它们添加到组件扫描中。如果您使用的是 Eclipse,则可以通过右键单击项目 -> 属性 -> java 构建路径 -> 源来将它们添加到构建路径中。您需要在此处添加src/<path to your additional source> 的路径并启用它,以便将其识别为源文件夹。然后你需要使用@ComponentScan 来扫描相关的包。这里的关键是将您的相关代码放入类路径中。

我能想到的一种情况是,您可能需要在target/generated-sources 下生成一些源代码,并且您需要使用这些存根或 bean 来开发代码。

【讨论】:

    【解决方案3】:

    最简单和最短的答案是您使用完全相同的方式扫描它们,类或包是否在 src/main/java 中并不重要,至少它应该在类路径中,以便 JVM 知道它并且已加载。

    如果 OP 的问题意味着包根本不在类路径中,则说:

    不在 src/main/java .. 即.. 你的类路径中

    这个问题没有意义,为什么要扫描不在 JVM 类路径中的包。即使您可以扫描它,您也无法使用它,因为它没有加载。

    【讨论】:

    • 原则上,可以手动将 .class 文件读入字节数组,然后以这种方式动态加载类。我认为在真正的软件中实际执行此操作并不好,但有可能做到。鉴于这是在一次采访中被问到的,“这没有意义”或“你不能”不是正确的答案。
    • 我完全同意。我的观点是,有人可以以不同的方式阅读 OP 的问题,即:不在 src/main/java 中,即您的类路径。我不确定这是否意味着不在 src/main/java 中,也不在类路径中,或者不在 src/main/java 中,而是在类路径中。
    • 无论哪种方式,都可以从文件系统打开文件,将其读入字节数组,然后以这种方式加载类。
    猜你喜欢
    • 2012-11-22
    • 2017-03-17
    • 1970-01-01
    • 2020-03-08
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-30
    相关资源
    最近更新 更多