Quarkus的拦截器ContainerRequestFilter注入Bean异常(19)

2023-11-18 13:17:13 浏览数 (1)

前言

今天升级了quarkus到最新版本1.8.0.final版本,然后就GG了,之前在ContainerRequestFilter注入的一个业务Bean就报错了,百度和Google 了半天没找到具体的解决方案,最后在一个不相干的论坛里找到了蛛丝马迹,然后解决了问题,所有这里记录下解决方案

出bug的代码

代码语言:javascript复制
@Priority(Priorities.USER   1)//值越大,优先级越小
@Provider
public class RequestLogFilter implements ContainerRequestFilter {
    
    @Inject
    LogService logService;
    
    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
           //保存请求日志
    }
}

这是一段拦截器代码,用于统一拦截请求记录请求的日志信息,注入的对象是一个日志服务对象,日志服务对象中包含了访问数据库的JPA对象EntityManager实例,然后就报错了

异常信息

代码语言:javascript复制
Caused by: java.lang.RuntimeException: Error injecting cn.keking.project.capital.thirdparty.repository.AppLogRepository cn.keking.project.capital.thirdparty.service.LogService.logRepository
	at cn.keking.project.capital.thirdparty.service.LogService_Bean.create(LogService_Bean.zig:166)
	at cn.keking.project.capital.thirdparty.service.LogService_Bean.get(LogService_Bean.zig:204)
	at cn.keking.project.capital.thirdparty.service.LogService_Bean.get(LogService_Bean.zig:239)
	at cn.keking.project.capital.thirdparty.filter.RequestLogFilter_Bean.create(RequestLogFilter_Bean.zig:331)
	... 54 more
Caused by: javax.enterprise.inject.CreationException: Synthetic bean instance for javax.persistence.EntityManager not initialized yet: javax_persistence_EntityManager_3cb728d15a0a04006cc75d03f784feb2bba9a5fb
	- a synthetic bean initialized during RUNTIME_INIT must not be accessed during STATIC_INIT
	- RUNTIME_INIT build steps that require access to synthetic beans initialized during RUNTIME_INIT should consume the SyntheticBeansRuntimeInitBuildItem
	at javax.persistence.EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.create(EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.zig:117)
	at javax.persistence.EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.create(EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.zig:140)
	at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:96)
	at io.quarkus.arc.impl.AbstractSharedContext.access$000(AbstractSharedContext.java:14)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:29)
	at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:26)
	at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
	at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
	at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:26)
	at javax.persistence.EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.get(EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.zig:172)
	at javax.persistence.EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.get(EntityManager_9b922d59b548563a5d960515e5e44f2bd846ceab_Synthetic_Bean.zig:188)
	at cn.keking.project.capital.thirdparty.repository.AppLogRepository_Bean.create(AppLogRepository_Bean.zig:170)
	at cn.keking.project.capital.thirdparty.repository.AppLogRepository_Bean.get(AppLogRepository_Bean.zig:207)
	at cn.keking.project.capital.thirdparty.repository.AppLogRepository_Bean.get(AppLogRepository_Bean.zig:242)
	at cn.keking.project.capital.thirdparty.service.LogService_Bean.create(LogService_Bean.zig:149)

异常的message中已说明了,在实例化filter的时候,EntityManager对象还未初始化,所有注入失败了。如果用异常message搜解决方案肯定都是搜索到quarkus的CDI文档,quarkus的CDI文档中确实给出了解决方案,但是实施起来比较复杂,最终博主在一个stackoverflow解答中找到了灵感解决了问题。

解决方案

代码语言:javascript复制
@Priority(Priorities.USER   1)//值越大,优先级越小
@Provider
public class RequestLogFilter implements ContainerRequestFilter {

    @Inject
    javax.inject.Provider<LogService> logService;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
       LogService log = logService.get();
           //保存请求日志
    }
}

看到区别了吧,注入的对象被javax.inject.Provider<LogService>接口包装了下,如此抽象作用域,以便可以从包含作用域的实例中查找范围较小的实例。使用的时候直接get()实例就可以获取到真实的业务Bean了

0 人点赞