springboot启动类
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、简单回顾
- 二、run方法的入参
- 三、ComponentScan的扫描范围
- 总结
前言
提示:这里可以添加本文要记录的大概内容:
springboot启动流程有很多文章都介绍得很详细了,今天我们换种方式来讨论下启动类。
提示:以下是本篇文章正文内容,下面案例可供参考
一、简单回顾
1、首先快速创建一个springboot项目,编写一个测试接口。
@RestController public class UserController {@RequestMapping("/test")public String getNameById(String id){System.out.println("测试接口入参,id="+id);return "lili";} }
接口正常,这是我们按默认方式创建项目。我们的启动类也很简单就是默认创建的。
2、下面我们来改造下启动类,demo1:将启动类的注解去掉,run方法入参换一个配置类
import com.jy.demo.config.AopConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;//@SpringBootApplication public class DemoApplication {public static void main(String[] args) {SpringApplication.run(AopConfig.class, args);} } import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.*;/*** @Author jy* @Date 2022/4/2 15:38* @Version 1.0*/ @Configuration @ComponentScan(basePackages = "com.jy.demo.controller") //@EnableAspectJAutoProxy @EnableAutoConfiguration //@Import(JyAfterFilter.class) public class AopConfig {}启动服务测试接口,发现服务正常启动,接口调用也是正常
从目前来看这样操作是没有问题。那么我们再来试试demo2的方式修改,先新建两个类具体位置如图
从图片中可以看出,main所在的类在app包下,配置类在最外层,这时我用TestApplication启动,服务也是正常运行,测试接口也是正常调用成功
3、我们再修改下代码,demo3:配置类也改一下
服务启动依然正常,接口测试也正常
我们几种修改都能正常启动,接口也正常调用,那么为什么可以呢?
二、run方法的入参
1、首先我们还是回顾下spring的注解模式
public class Demo9 {public static void main(String[] args) {ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopConfig.class);applicationContext.publishEvent(new ApplicationEvent("监听事件推送") {});Apple bean = applicationContext.getBean(Apple.class);bean.setId(1);System.out.println(bean);} } public void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register").tag("classes", () -> Arrays.toString(componentClasses));this.reader.register(componentClasses);//注意这行代码!!!!registerComponentClass.end();}传入的参数就是一个配置类,spring先将这个配置类注入容器,然后在BeanFactoryPostProccsor的实现中处理配置类带来的该处理的对象。具体的操作可以看看Configuration注解解析,而springboot的启动类中的run方法入参是什么呢?其实也是一个配置类,那么springboot是怎么用这个配置类的呢?
首先是将这个配置类放在SpringApplication的成员变量里,然后在run方法中的上下文应用准备的时候对配置类进行了处理。
往下一步就是在load()方法中加载
这里因为我们看的配置类,所以进入第一个if中,再往里走就到了我们前面spring处理时的类似代码了
圈上的这行代码和前面提示注意的那行代码就是一个意思了,到目前为止说清楚了,这个配置类被注册到容器的过程,那么和我们启动类的位置有什么关系呢?
三、ComponentScan的扫描范围
细心的朋友可能已经发现,我们几次修改的时候配置类的ComponentScan的value值是有所不同的,@SpringBootApplication的value值是默认空,而自己写的配置类上的ComponentScan注解是加了路径值的。两者的区别在于,默认空的话,扫描路径是按配置类所在的位置扫描同级及下级;有值的话就按填写的值进行扫描同级及下级。这个操作在ConfigurationClassPostProcessor类处理配置类信息时处理的。而配置类的信息在前面已经说了是怎么注册到容器中的,所以spring能处理到我们的启动配置类,也顺其自然的能处理到配置类上的扫描范围。所以虽然我们修改了main方法文件所在的位置,修改了配置类的位置服务依然能正常启用,接口也正常调用。
总结
唉,前面屁话了一堆,第三点就这么点东西说明了原因。最后再多一嘴,
既然启动类的位置可以不在最外层,那springboot为什么要放在最外层呢?因为springboot不知道我们会写些什么包路径,所以放最外层从最外层往下扫描,将对象是否注入容器交给开发者(需要注入就加注解)。以上就是我的一点个人理解,欢迎大家斧正。大家一起加油!!!
总结
以上是生活随笔为你收集整理的springboot启动类的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 洛谷P3369 AVL树
- 下一篇: 网页版飞信(Fetion)的安全问题