Jersey 2.26迁移:自定义注入注解配置问题求助
Jersey 2.26 自定义注解注入完整实现示例
我刚好在迁移类似的Jersey项目到2.26版本时踩过同样的坑,给你一个完整的可运行示例,一步步解决你的问题:
1. 定义自定义注入注解
首先是你的@SessionInject注解,保持和之前一样的定义即可,确保元注解配置正确:
import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @Retention(RUNTIME) @Target({FIELD, PARAMETER}) public @interface SessionInject { }
2. 实现Supplier(替代HK2 Factory)
按照Paul的方案,用Supplier代替旧的HK2 Factory来提供要注入的实例,比如你的Session对象:
import javax.inject.Singleton; import java.util.function.Supplier; @Singleton public class SessionSupplier implements Supplier<Session> { @Override public Session get() { // 这里实现你的Session实例获取逻辑,比如从线程上下文、请求中获取 return new Session(); // 替换成实际的获取逻辑 } }
3. 实现InjectionResolver
在Jersey 2.26中,直接实现org.glassfish.hk2.api.InjectionResolver即可,不需要继承InjectionResolverWrapper(除非你需要包装其他解析器做扩展)。这里我们实现针对@SessionInject的解析器:
import org.glassfish.hk2.api.InjectionResolver; import org.glassfish.hk2.api.ServiceHandle; import javax.inject.Inject; import javax.inject.Singleton; @Singleton public class SessionInjectResolver implements InjectionResolver<SessionInject> { private final SessionSupplier sessionSupplier; @Inject public SessionInjectResolver(SessionSupplier sessionSupplier) { this.sessionSupplier = sessionSupplier; } @Override public Object resolve(Injectee injectee, ServiceHandle<?> root) { // 这里返回要注入的实例,直接调用Supplier的get方法 return sessionSupplier.get(); } @Override public boolean isConstructorParameterIndicator() { return false; } @Override public boolean isMethodParameterIndicator() { return false; } }
4. 正确绑定解析器(解决编译失败问题)
你之前的绑定代码编译失败,问题出在TypeLiteral的使用和绑定方式上。需要在自定义的AbstractBinder中完成所有绑定,注意要指定解析器的泛型类型:
import org.glassfish.hk2.api.TypeLiteral; import org.glassfish.jersey.internal.inject.AbstractBinder; public class CustomInjectionBinder extends AbstractBinder { @Override protected void configure() { // 绑定SessionSupplier bind(SessionSupplier.class).to(Session.class).in(Singleton.class); // 关键:正确绑定SessionInjectResolver到带泛型的InjectionResolver类型 bind(SessionInjectResolver.class) .to(new TypeLiteral<InjectionResolver<SessionInject>>() {}) .in(Singleton.class); } }
5. 将Binder注册到Jersey应用
最后,在你的Jersey应用配置类中注册这个自定义Binder:
import org.glassfish.jersey.server.ResourceConfig; public class JerseyAppConfig extends ResourceConfig { public JerseyAppConfig() { // 注册你的资源类包路径 packages("com.your.package.resources"); // 注册自定义注入绑定器 register(new CustomInjectionBinder()); } }
测试使用
现在你就可以在资源类中直接使用@SessionInject注解注入Session了:
import javax.ws.rs.GET; import javax.ws.rs.Path; @Path("/test") public class TestResource { @SessionInject private Session session; @GET public String getSessionInfo() { return "Session ID: " + session.getId(); // 替换成实际的Session方法 } }
关键说明
- 不需要继承
InjectionResolverWrapper,直接实现InjectionResolver即可满足基本自定义注入需求; - 绑定解析器时必须使用
TypeLiteral来指定泛型类型InjectionResolver<SessionInject>,否则HK2无法正确识别解析器对应的注解; - 确保所有组件都通过HK2管理(比如用
@Singleton或其他作用域注解),避免实例创建问题。
内容的提问来源于stack exchange,提问作者Hank
相关产品推荐
相关产品推荐

