Thursday, 15 July 2010

java - Using a custom hk2 InjectionResolver to inject application configuration -



java - Using a custom hk2 InjectionResolver to inject application configuration -

kind of follow my previous question. i'm trying inject application configuration info using jsr-330 standard annotations , hk2 framework bundled jersey.

ideally i'd create custom injectionresolver named annotation, lookup desired values in map or properties object populate info read elsewhere. in first effort i've created application instance like

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) } }); }

and injectionresolver looks like

public class configurationinjectionresolver implements injectionresolver<named> { @context application application; @override public object resolve(injectee injectee, servicehandle<?> servicehandle) { // lookup info in application.getproperties(); } }

my problem application.getproperties() empty. thought what's wrong? also, bind instance of injector instead of binding class? way build instance passing map info parameter.

"my problem application.getproperties() empty. thought what's wrong?

no. works fine me.

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)); homecoming props.get(name); } @override public boolean isconstructorparameterindicator() { homecoming false; } @override public boolean ismethodparameterindicator() { homecoming 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); } }); } }

resource

@path("/config") public class configresource { @named("hello.config") string hello; @get public response gethello() { homecoming response.ok(hello).build(); } }

c:\>curl http://localhost:8080/test/rest/config hello world property

personally though, in situation, create own annotation, not override existing functionality of @named annotation.

another cool option

hk2 has configuration extension, can load properties object .properties file , and have properties automatically injected @configured annotation. couldn't find documentation on this, there illustration usage of in hk2 source code examples.

here's illustration implementation

required dependencies. check bailiwick of jersey version , see hk2 version depends on. in case bailiwick of jersey 2.13 uses hk2 2.3.0-b10, should ${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); seek { loadconfigurationproperties(locator); } grab (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!

resource

@path("/config") @configuredby("appconfiguration") public class configresource { @configured string hello; @get public response gethello() { homecoming response.ok(hello).build(); } }

c:\>curl http://localhost:8080/test/rest/config hello squirrel property!

diclaimer: since feature isn't documented, not sure if have implementation here. trial , error. instance this

servicelocatorutilities.addclasses(locator, configresource.class);

i sense shouldn't necessary. seems redundant, bundle scanning. explicitly add together configresource locator context doesn't seem right me.

java dependency-injection jersey-2.0 hk2

No comments:

Post a Comment