springbootrun方法什么时候扫描的配置类

springbootrun方法什么时候扫描的配置类,第1张

SpringBootRun方法会在应用启动时扫描配置类。SpringBootRun方法是一个静态方法,它可以接受一个参数,该参数是一个字符串数组,其中包含要传递给应用程序的参数。SpringBootRun方法会调用SpringApplication类的run方法,该方法会接受一个参数,该参数是一个配置类,它包含了应用程序所需的所有配置信息。在调用run方法之后,SpringBootRun方法会扫描该配置类,以确定应用程序需要加载哪些组件。一旦所有组件都被加载,应用程序就可以正常运行了。

说明你的spring boot启动时的application类不在iogithubgefangshuaiapp及其子包下。

SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描的。“Application类”是指SpringBoot项目入口类。如果Application类所在的包为:iogithubgefangshuaiapp,则只会扫描iogithubgefangshuaiapp包及其所有子包,如果service或dao所在包不在iogithubgefangshuaiapp及其子包下,则不会被扫描。

改变这种扫描包的方式的原理很简单:用@ComponentScan注解进行指定要扫描的包以及要扫描的类。

可以用以下方式测试:

第一步:新建两个包cnkfit ; orgkfit;

第二步:新建两个测试类;

在这里为了方便测试,我们让我们的类在启动的时候就进行执行,所以就编写两个类,实现接口CommandLineRunner,这样在启动的时候我们就可以看到打印信息了。

cnkfitMyCommandLineRunner1  :

package cnkfit;  
  
import orgspringframeworkbootCommandLineRunner;  
  
@Configuration  
publicclass MyCommandLineRunner1 implements CommandLineRunner {  
  
    @Override  
    publicvoid run(String args) throws Exception {  
       Systemoutprintln("MyCommandLineRunner1run()");  
  
    }  
}

orgkfitMyCommandLineRunner2  :

package orgkfit;  
  
import orgspringframeworkbootCommandLineRunner;  
  
  
@Configuration  
publicclass MyCommandLineRunner2 implements CommandLineRunner {  
  
    @Override  
    publicvoid run(String args) throws Exception {  
  
       Systemoutprintln("MyCommandLineRunner2run()");  
  
    }  
  
}

第三步:启动类进行注解指定;
在Appjava类中加入如下注解:

//可以使用:basePackageClasses={},basePackages={}  
@ComponentScan(basePackages={"cnkfit","orgkfit"})

启动时如果看到打印信息:

则说明配置成功。

简单demo
使用 maven 构建项目,官方现在稳定版本是154,第一个入门demo不是web项目,pom依赖如下:

实体 User 类:

配置类:

入口类 Application :

项目结构目录

启动程序,以 main 方法启动:

打印出正确的结果。

来分析一下流程,为何 Runnable 类, User , Map 会纳入spring容器

首先我们分析的就是入口类 Application 的启动注解 @SpringBootApplication ,进入源码:

发现 @SpringBootApplication 是一个复合注解,包括 @ComponentScan ,和 @SpringBootConfiguration , @EnableAutoConfiguration 。

根据上面的理解,上面的入口类 Application ,我们可以使用:

使用 @ComponentScan 注解代替 @SpringBootApplication 注解,也可以正常运行程序。原因是 @SpringBootApplication 中包含 @ComponentScan ,并且 springboot 会将入口类看作是一个 @SpringBootConfiguration 标记的配置类,所以定义在入口类 Application 中的 Runnable 也可以纳入到容器管理。

看一个demo学会使用这些参数配置
在包下comzhihaomiaospringboot定义一个启动应用类(加上@SpringBootApplication注解)

在comzhihaomiaobeans包下定义一个实体类,并且想将其纳入到spring容器中,

启动启动类,打印结果如下:

说明Cat类并没有纳入到spring容器中,这个结果也如我们所想,因为@SpringBootApplication只会扫描@SpringBootApplication注解标记类包下及其子包的类(特定注解标记,比如说@Controller,@Service,@Component,@Configuration和@Bean注解等等)纳入到spring容器,很显然MyConfig不在@SpringBootApplication注解标记类相同包下及其子包的类,所以需要我们去配置一下扫包路径。

修改启动类,@SpringBootApplication(scanBasePackages = "comzhihaomiao"),指定扫描路径:

启动并打印:

当然使用@SpringBootApplication(scanBasePackageClasses = MyConfigclass),指定scanBasePackageClasses参数的value值是你需要扫描的类也可以,结果一样,不过如果多个配置类不在当前包及其子包下,则需要指定多个。

再看一个列子,
在上面的列子的相同包下(comzhihaomiaospringboot)配置了People,并将其纳入到spring容器中(@Component),我们知道@SpringBootApplication注解会扫描当前包及其子包,所以People类会纳入到spring容器中去,我们需要将其排除在spring容器中,如何 *** 作?
可以使用@SpringBootApplication的另外二个参数(exclude或excludeName)

启动类,

启动并打印结果:

然后修改@SpringBootApplication配置,

很明显启动报错。使用@excludeName注解也可以。如下,
@SpringBootApplication(excludeName = {"comzhihaomiaospringbootPeople"})

参考文档:
Springboot154官方文档

Spring注解自动扫描Jar中的类,以前在eclipse下,打包时需要选择Add directory entries选项,否则spring是不会扫描该jar的。
在maven下,打包时需要指定添加
Java代码
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>

  导致问题的主要原因是不了解SpringBoot注解扫描范围约定,将启动文件Applicationjava在package中定义的层次过深。
SpringBoot注解扫描范围约定
  SpringBoot项目的注解扫描默认规则是根据Application类所在的包位置从上往下扫描!“Application类”是指SpringBoot项目入口类。这个类的位置很关键。如果Application类所在的包为:commakeronly,则只会扫描commakeronly包及其所有子包,如果controller、service或dao所在包不在commakeronly及其子包下,则不会被扫描!
  如果Application类放在commakeronlypay包中,那么与pay的同级包、父级包是不会被扫描的。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13399392.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-29
下一篇 2023-07-29

发表评论

登录后才能评论

评论列表(0条)

保存