发布于 

has not been refreshed yet

本地导出的jar包运行正常,通过Jenkins打包部署到k8s上启动报错:has not been refreshed yet
报错详细信息如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2023-01-03 13:27:29.644|1672723649644|nioEventLoopGroup-7-28|WARN ||||||i.n.c.ChannelInitializer:97|Failed to initialize a channel. Closing: [id: 0x79bae2b1, L:/10.42.0.72:7121 - R:/10.42.0.1:58054]
java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@bef2d72 has not been refreshed yet
at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1096)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1126)
at io.btg.gts.quote.handler.MessageHandler.<init>(MessageHandler.java:95)
at io.btg.gts.quote.server.WebSocketInitializer.initChannel(WebSocketInitializer.java:35)
at io.btg.gts.quote.server.WebSocketInitializer.initChannel(WebSocketInitializer.java:17)
at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:129)
at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:112)
at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:938)
at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:609)
at io.netty.channel.DefaultChannelPipeline.access$100(DefaultChannelPipeline.java:46)
at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1463)
at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1115)
at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:650)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:502)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:417)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:474)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:829)

分析日志,感觉是程序启动的时候,获取类对象没有成功导致服务启动失败。
而我没有改动其他代码,只是在上一版的基础上增加了新功能,从新增的代码入手,定位到了问题应该出现在getBean上。
新增的代码里面有一个工厂类,负责管理和生产数据,但由于是单例,该例调用其他服务时我用的getBean给服务赋值。
之所以没用依赖注入,因为用依赖注入会导致数据不正常,而现在由于用getBean有问题,所以只能回到依赖注入的解决方案上。
修改代码,把getBean改为依赖注入,发现数据果然开始不对,打断点跟踪代码运行时发现,依赖注入,对象是成功的注入到了工厂类里,但是输出数据的时候,数据为空。
当时有点懵逼,同样的代码,只不过服务赋值方式不一样,但可以肯定都是成功赋值了的,运行结果却不相同,问题出在哪里?
一番分析后感觉框架底层在注入数据的时候操作的对象并不是该工厂的单例,所以打断点分析的时候各方面都是有值的,但是一到单例数据输出却为空。
解决方案参考如下,把单例和当前操作对象进行一个关联。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Component
public class DBManager {

private static DBManager instance = new DBManager();
@Autowired
public UserServiceImpl userService;

private DBManager() {
}

public static DBManager getInstance() {
return instance;
}

@PostConstruct
public void init() {
instance = this;
instance.userService = this.userService;
}
}

运行,测试,成功解决。