Spring Boot 项目启动报错: Unable to start embedded

作者: wencst 分类: JAVA,架构设计,程序设计 发布时间: 2025-01-22 20:17 阅读: 191 次

现象

当服务启动时,报错:

java.lang.NullPointerException: null
	at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:240)
	at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:270)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:106)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4566)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5203)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909)
	at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:843)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384)
	at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
	at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909)
	at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.StandardService.startInternal(StandardService.java:421)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
	at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:105)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:86)
	at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:416)
	at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:180)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:180)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:153)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)

 

分析代码GenericFilterBean


	protected final Log logger = LogFactory.getLog(getClass());
	if (logger.isDebugEnabled()) {
		logger.debug("Filter '" + filterConfig.getFilterName() + "' configured for use");
	}

其中logger为空

 

分析原理

CGLIB原理: 动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。

1.主要原因由于org.springframework.web.filter.GenericFilterBean的子类A的代理对象的logger属性为空引发的空指针异常
2.AOP 注解@Aspect。对应切点配置的路径下类会由CGLIB(SpringBoot默认)动态代理生成.

@Pointcut("execution(public * com.example.handler..*.*(..))")

3.包com.example.handler下的类A继承了OncePerRequestFilter

4.由于CGLIB原理, 生成类A的代理对象时, final声明的属性将为空

5.GenericFilterBean执行init()方法到类A时,由于类A的代理对象的logger属性为空, 导致logger.isDebugEnabled()报空指针异常

 

解决方法

1.将继承OncePerRequestFilter的类A移出对应包路径com.example.handler,使得切片不切A这个Filter
2.逻辑选一,要么使用切片,要么使用Filter

如果文章对您有用,扫一下支付宝的红包,不胜感激!

欢迎加入QQ群进行技术交流:656897351(各种技术、招聘、兼职、培训欢迎加入)



Leave a Reply