my previous question的后续行动。我正在尝试使用JSR-330标准注释和与泽西捆绑的HK2框架注入应用程序配置数据。
理想情况下,我想为InjectionResolver
注释创建自定义Named
,该注释将在我将填充的Map
或Properties
对象中查找所需的值从其他地方的数据读在我的第一次尝试中,我创建了一个Application
实例,如
public class MyApplication extends ResourceConfig {
...
packages(MY_PACKAGES);
property(MY_CONFIG_PROPERTY, someValue);
register(new AbstractBinder() {
@Override
protected void configure() {
bind(ConfigurationInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<Named>>(){})
.in(Singleton.class)
}
});
}
然后我的InjectionResolver
看起来像
public class ConfigurationInjectionResolver implements InjectionResolver<Named> {
@Context Application application;
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> serviceHandle) {
// lookup data in application.getProperties();
}
}
我的问题是application.getProperties()
是空的。知道什么是错的吗?另外,我可以绑定我的Injector实例而不是绑定类吗?这样我就可以构造将Map
数据作为参数传递的实例。
答案 0 :(得分:5)
“我的问题是application.getProperties()是空的。知道什么是错的吗?
没有。这实际上对我来说非常好。
public class ConfigurationInjectionResolver implements InjectionResolver<Named> {
@Context
Application application;
@Override
public Object resolve(Injectee injectee, ServiceHandle<?> root) {
Named annotation = injectee.getParent().getAnnotation(Named.class);
Map<String, Object> props = application.getProperties();
String name = annotation.value();
System.out.println(props.get(name));
return props.get(name);
}
@Override
public boolean isConstructorParameterIndicator() { return false; }
@Override
public boolean isMethodParameterIndicator() { return false; }
}
@ApplicationPath("/rest")
public class JerseyApplication extends ResourceConfig {
public JerseyApplication() {
packages("jersey.startup.test");
property("hello.config", "Hello World Property");
register(new AbstractBinder() {
@Override
protected void configure() {
bind(ConfigurationInjectionResolver.class)
.to(new TypeLiteral<InjectionResolver<Named>>() {
}).in(Singleton.class);
}
});
}
}
资源
@Path("/config")
public class ConfigResource {
@Named("hello.config")
String hello;
@GET
public Response getHello() {
return Response.ok(hello).build();
}
}
C:\>curl http://localhost:8080/test/rest/config
Hello World Property
就个人而言,在这种情况下,我会创建自己的注释,以便不覆盖@Named
注释的任何现有功能。
HK2有一个配置扩展,您可以从Properties
文件加载.properties
对象,并使用@Configured
注释自动注入这些属性。我找不到任何关于此的文档,但在HK2 source code examples中有一个示例用法。
这是一个示例实现
必需的依赖项。检查泽西岛版本,看看它依赖的HK2版本。在我的情况下,泽西岛2.13使用HK2 2.3.0-b10,因此应该是${hk2.version}
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-configuration-hub</artifactId>
<version>${hk2.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-configuration-integration</artifactId>
<version>${hk2.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-property-file</artifactId>
<version>${hk2.version}</version>
</dependency>
App config
@ApplicationPath("/rest")
public class JerseyApplication extends ResourceConfig {
@Inject
public JerseyApplication(ServiceLocator locator) {
packages("jersey.startup.test");
ServiceLocatorUtilities.addClasses(locator, ConfigResource.class);
try {
loadConfigurationProperties(locator);
} catch (IOException ex) {
Logger.getLogger(JerseyApplication.class.getName())
.log(Level.SEVERE, null, ex);
}
}
private void loadConfigurationProperties(ServiceLocator locator)
throws IOException {
ConfigurationUtilities.enableConfigurationSystem(locator);
PropertyFileUtilities.enablePropertyFileService(locator);
PropertyFileService propertyFileService
= locator.getService(PropertyFileService.class);
Properties props = new Properties();
URL url = getClass().getResource("/configuration.properties");
props.load(url.openStream());
PropertyFileHandle propertyFileHandle
= propertyFileService.createPropertyHandleOfAnyType();
propertyFileHandle.readProperties(props);
}
}
configuration.properties
AppConfiguration.App.hello=Hello Squirrel Property!
资源
@Path("/config")
@ConfiguredBy("AppConfiguration")
public class ConfigResource {
@Configured
String hello;
@GET
public Response getHello() {
return Response.ok(hello).build();
}
}
C:\>curl http://localhost:8080/test/rest/config
Hello Squirrel Property!
Diclaimer:由于此功能没有详细记录,我不确定我是否在这方面做得很好。只是通过反复试验。比如这个
ServiceLocatorUtilities.addClasses(locator, ConfigResource.class);
我觉得不应该是必要的。这似乎是多余的,因为我已经是打包扫描。因此,将ConfigResource
显式添加到定位器上下文对我来说似乎并不合适。