在Spring boot中有扫描注解,当没有指定扫描路径的时候,扫描当前类所在的包
1.启动spring容器
2.启动spring容器之后,我们默认加载的是tomcat,那么怎么切换,不只是使用tomcat,还可以使用其他的,比如jetty等
1⃣️ 我们首先需要使用<Excution>注解先将tomcat设置为不可见的,然后添加jetty的依赖
2⃣️添加上面的依赖之后我们就实现了切换了吗?不是的❌
我们还需要添加判断,判断当前我们添加的到底是哪个依赖
那么怎么实现?
我们首先想到的是可以使用条件语句进行判断,但是这种方法的判断多少有点不合适,那么我们可以使用更高级的-----webServer
实现:我们创建对应的类分别实现web server接口【如下所示】
创建了对应的类之后我们怎么将其对应的实现添加进来?
可以使用bean
这个时候又会有一个问题❓----- 怎么进行判断?由多个bean怎么办?
解决办法🪝:使用java内部的API-----beanoftype,里面有一些条件判断,实现只可以允许一个bean的存在,实现如下图所示
【这里补充一个小的知识点:jetty的依赖导入--- jetty- server】
既然我们已经实现了每次只加载一个bean,问题:❓那么bean是怎么定义的,也就是java对应的类中怎么实现的?
解决办法🪝:由Spring boot自动配置,也就是使用webserverautoconfiguration这个类
那么这个类是怎么实现的?
如下图所示:
实现了这个类之后,两个bean都会加载【tomcat和jetty】
问题❓:怎么实现两个bean不同时加载?
解决办法🪝:当存在依赖的时候在加载,不存在就不加载
【这里补充一点知识点:在Spring boot中,两个依赖必须同时有,但是在我们实现的user中只加载我们user需要的
在这里:现在是user--(依赖)--》Spring boot--(依赖)--》tomcat、jetty
所以如果不实现依赖根据需求加载的话,两个依赖同时都会加载 】
解决办法🪝:在Spring boot的pom.xml文件中添加<option>true<option>到jetty【作用:不让依赖传递】
在user的pom.xml文件里面添加<exclution>到tomcat上,然后加载jetty就可以实现加载jetty了【因为Spring boot默认加载tomcat】
问题❓:那么bean怎么操作🐶,有没有更好的判断方式
解决方法🪝:使用条件注解@conditional()【spring的条件注解】判断当前有没有tomcat活着jetty依赖
【tomcatcondition implement condition】
如下图所示:
那么我们会发现,两个实现很像。 问题❓:那么有没有改进的办法?
解决办法🪝:我们可以提取公共部分,使用@conditiononclass条件注解实现【这个是spring boot的条件注解】
目标【如下图所示】:
如何实现?【实现过程如下所示】
这个注解里面引用了@conditional注解
问题❓:实现之后我们运行,会发现异常,为什么?
因为扫描,我们会发现当前扫描的是user下面的包,但是扫描不到Spring boot下的包
解决办法🪝:让webserver..configuration扫描到,使用import导入
【如下图所示】
这里只是引入了一个实现类🐶,问题❓:那么需要引入更多的时候怎么办?
解决办法🪝:使用@deferredimportselector导入
问题❓:实现后我们知道导入的是多个配置类的名字,那么怎么获取名字?
解决办法🪝:使用spi机制【spring.factories】【如下图所示】
那么源码怎么找?【如下图所示】
问题❓:怎么生成的matadata?
使用abstract processor【lomnok也是使用它实现的】