SpringBoot的项目除了像Spring打包成war包运行以外,因为内置Tomcat,所以也可以打包成jar包运行,两种不同的运行模式在大部分情况下只是打包运行模式不同,对业务代码是没有影响的,但是也会有些细微的区别,这里列出一些在实际项目工作中遇到的情况:
一、监听器的不同注册方式(Servlet和Filter一样,这里以Listener的session监听器为代表讲述案例)
1、@WebListener注解加实现HttpSessionListener接口
@WebListener
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("destroyed...");
}
}
以这种形式在war模式下能正常运行,但是在jar模式下这个监听器无法注册,因为SpringBoot没有自动扫描@WebListener注解下的类,需要在启动类上增加@ServletComponetScan注解方可
@SpringBootApplication
@ServletComponentScan
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
此时如果在监听器中增加一个bean注入
@WebListener
public class SessionListener implements HttpSessionListener {
@Resource(name = "ResourceService")
private IResourceService resourceService;
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("destroyed...");
}
}
以这种形式在war模式下会启动失败,因为无法注入ResourceService这个bean;但是在jar模式下是能注入bean正常运行的。
2、@Component注解加实现HttpSessionListener接口
@Component
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("destroyed...");
}
}
以这种形式在war模式下和jar模式下都能正常注册运行。即时在监听器中增加一个bean注入,这两种模式下也都能正常注入bean、注册监听器与正常运行。
3、@WebListener+@Component注解加实现HttpSessionListener接口
@Component
@WebListener
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("destroyed...");
}
}
这样相当于这个监听器被注册了两次,也就是session销毁时,会输出两次destroyed...;(有一种情况下只注册一次:jar模式下,且启动类上没有@ServletComponetScan注解,因为这样@WebListener注解会失效,也就相当于只有@Component注解)
1、bean能否注入
2、监听器能否注册 | war |
jar
|
@Component
|
1、
@Resource的
bean自动注入
2、注册成功
|
1、@Resource的bean自动注入
2、注册成功
|
@
WebListener
|
1、
@Resource的
bean注入失败导致启动失败
2、注册成功
|
1、@Resource的bean自动注入
2、需要
需要在启动类上额外增加@ServletComponentScan注解
|
@Component
+
@
WebListener
|
1、@Resource的bean注入失败导致启动失败
2、注册成功
|
1、
@Resource的
bean注入失败导致启动失败
2、注册成功
3、该监听器会被注册两次(只有一种情况导致@WebListener失效的除外)
|
原因解析: