I have been learning about Guice. I see that there is an on-demand injection here.
I wanted to know what it is used for and some example. I have a scenario where I read a set of properties from a conf file. There is no injection there. Later on I want to inject the same instance of the config class I have from those properties to some other class.
class Props {
//set of properties read from a config file to this class
}
Props props = readProperties(); // instance of this class having all the properties but not put into injection container
Later in connection class I want to use its injection
#Inject
public Connection(Props props) {
this.props = props;
}
Is it possible to use on-demand injection of Guice in this case? Also I am using Play framework's conf file to load my module file.
play.modules.enabled += com.example.mymodule
If you want to use the very same configuration instance (of class Props) you could bind its instance as a singleton with a provider binding. This is of course not the only solution, but it makes sense for me.
Here is an example:
Define a provider:
public class PropsProvider implements Provider<Props>
{
#Override
public Props get()
{
...read and return Props here...
}
}
Use a provider binding in singleton scope:
bind(Props.class).toProvider(PropsProvider.class).in(Singleton.class);
Inject your configuration:
#Inject
public Connection(Props props) {
this.props = props;
}
You may read in the documentation:
Singletons are most useful for:
stateful objects, such as configuration or counters
objects that are expensive to construct or lookup
objects that tie up resources, such as a database connection pool.
Maybe your configuration object matches the first and the second criteria. I would avoid reading the configuration from within the module. See why here.
I've used on-demand injection in a few unit test cases where I wanted to inject mock dependencies in the component under test and field injection was used (that's why I try to avoid field injections :-) ) AND I preferred not to use InjectMocks for certain reasons.
Here is a sample:
Component:
class SomeComponent
{
#Inject
Dependency dep;
void doWork()
{
//use dep here
}
}
The test itself:
#RunWith(MockitoJUnitRunner.class)
public class SomeComponentTest
{
#Mock
private Dependency mockDependency;
private SomeComponent componentToTest;
#Before
public void setUp() throws Exception
{
componentToTest = new SomeComponent();
Injector injector = Guice.createInjector(new AbstractNamingModule()
{
#Override
protected void configure()
{
bind(Dependency.class).toInstance(mockDependency);
}
});
injector.injectMembers(componentToTest);
}
#Test
public void test()
{
//test the component and/or proper interaction with the dependency
}
}
Load the properties in your module and them via bindConstant
Related
My goal is to add some additional logic around the System Injection Resolver (to decorate it, so to speak). Basically, I want to register a custom injection resolver (e.g. described here), but for the javax.inject.#Inject Annotation. The setup works if I create a different custom annotation, but not when using #Inject. My implementation is as follows:
Injection Resolver:
#Singleton
#Rank(Integer.MAX_VALUE)
public class InjectInjectionResolver
implements InjectionResolver<Inject> {
private final InjectionResolver<Inject> injectionResolver;
#Inject
public InjectInjectionResolver(
#Named(InjectionResolver.SYSTEM_RESOLVER_NAME) final InjectionResolver<Inject> injectionResolver) {
this.injectionResolver = injectionResolver;
}
#Override
public Object resolve(final Injectee injectee, final ServiceHandle<?> root) {
throw new RuntimeException("Why is this never called?");
}
#Override
public boolean isConstructorParameterIndicator() {
return injectionResolver.isConstructorParameterIndicator();
}
#Override
public boolean isMethodParameterIndicator() {
return injectionResolver.isMethodParameterIndicator();
}
}
And I register the resolver as follows (inside ResourceConfig):
register(new AbstractBinder() {
#Override
protected void configure() {
bind(InjectInjectionResolver.class).to(new GenericType<InjectionResolver<Inject>>() {}).in(Singleton.class);
}
});
What I tried so far:
using #Rank
using both the org.glassfish.jersey.internal.inject.AbstractBinder or org.glassfish.hk2.utilities.binding.AbstractBinder with TypeLiteral, along with implementing the org.glassfish.hk2.api.InjectionResolver or org.glassfish.jersey.internal.inject.InjectionResolver
making sure the same setup works with #CustomAnnotation (where both the constructor and the resolve methods are called)
Does anyone know how to solve this issue?
Versions used: jersey 2.27
EDIT: When I #Inject the InjectionResolver itself, it seems that hk2's org.jvnet.hk2.internal.ThreeThirtyResolver is injected for the org.glassfish.hk2.api.InjectionResolver, while my custom injection resolver is injected for org.glassfish.jersey.internal.inject.InjectionResolver. However, the custom injection resolver is not used for injection.
The following configuration works for me, thanks to #jwells131313 for bringing me back on track. I tried to use fully qualified names, else it's probably from the javax.inject.* package.
#Singleton
#Rank(Integer.MAX_VALUE)
#org.jvnet.hk2.annotations.Service
public class MyHk2InjectionResolver
implements org.glassfish.hk2.api.InjectionResolver<Inject> {
private final org.glassfish.hk2.api.InjectionResolver<Inject> injectionResolver;
#Inject
public MyHk2InjectionResolver(
#Named(org.glassfish.hk2.api.InjectionResolver.SYSTEM_RESOLVER_NAME) final org.glassfish.hk2.api.InjectionResolver<Inject> injectionResolver) {
this.injectionResolver = injectionResolver;
}
// ... required methods, could just delegate to system resolver
}
To register the resolver, we bind it to the correct type (I do it in the ResourceConfig of a jersey application):
register(new org.glassfish.hk2.utilities.binding.AbstractBinder() {
#Override
protected void configure() {
bind(MyHk2InjectionResolver.class)
.to(new org.glassfish.hk2.api.TypeLiteral<org.glassfish.hk2.api.InjectionResolver<Inject>>() {})
.in(Singleton.class);
}
});
With this setup, you can keep using the #Inject annotation and write some custom injection logic around it, possibly using the default system injection resolver as a fallback.
I try to benchmark some of the methods of my Spring (with maven) project. I need to use #Autowired and #Inject on several fields in my project. While I run my project, it works well. But JMH always gets NullPointerException with #Autowired/#Inject fields.
public class Resources {
private List<Migratable> resources;
#Autowired
public void setResources(List<Migratable> migratables) {
this.resources = migratables;
}
public Collection<Migratable> getResources() {
return resources;
}
}
My Benchmark class
#State(Scope.Thread)
public class MyBenchmark {
#State(Scope.Thread)
public static class BenchmarkState {
Resources res;
#Setup
public void prepare() {
res = new Resources();
}
}
#Benchmark
public void testBenchmark(BenchmarkState state, Blackhole blackhole) {
blackhole.consume(state.res.getResources());
}
}
When I run my benchmark, it get NullPointerException at Resources.getResources()
More specifically at resources.
It cannot Autowire setResources(). But if I run my project(exclude benchmark), it works fine.
How can I get rid of this NullPointerException with Autowired field while benchmarking?
Here is an example of how to run Spring-based benchmarks: https://github.com/stsypanov/spring-boot-benchmark.
Basically what you need is to store a reference to your application context as a field of benchmarks class, initialize the context in #Setup method and close it in #TearDown. Something like this:
#State(Scope.Thread)
#OutputTimeUnit(TimeUnit.MICROSECONDS)
#BenchmarkMode(value = Mode.AverageTime)
public class ProjectionVsDtoBenchmark {
private ManyFieldsRepository repository;
private ConfigurableApplicationContext context;
#Setup
public void init() {
context = SpringApplication.run(Application.class);
context.registerShutdownHook();
repository = context.getBean(ManyFieldsRepository.class);
}
#TearDown
public void closeContext(){
context.close();
}
}
The logic that you are going to measure must be encapsulated in a method of Spring component called from #Benchmark annotated method. Remember general rules of benchmarking to make sure your measurements are correct, e.g. use Blackhole or return value from the method to prevent compiler from DCE.
Try to use
#RunWith(SpringJUnit4ClassRunner.class) and #ContextConfiguration(locations = {...}) on the test class. This should initialize Spring TestContext Framework and let you autowire dependencies.
If this doesn't work, then you have to start Spring ApplicationContext explicitly as a part of you #Setup annotated method, using either of
ClassPathXmlApplicationContext, FileSystemXmlApplicationContext or
WebXmlApplicationContext and resolve beans from that context:
ApplicationContext context = new ChosenApplicationContext("path_to_your_context_location");
res = context.getBean(Resources.class);
I've seen one of the program where MyConfig(Spring Configuration file) is being referenced in constructor of one of the bean in order to get other bean defined in MyConfig.
I am not sure about this kind of configuration. I can see cyclic reference in this kind of code, though it is working fine but I am not able to understand the flow. How it is working. Below is the replica of that code -
#Configuration
public class MyConfig {
#Bean(name="a")
#Scope("prototype")
public A getA() {
return new A();
}
#Bean(name="b")
#Scope("prototype")
public B getB() {
return new B();
}
#Bean(name="c")
#Scope("prototype")
public C getC() {
return new C();
}
#Bean(name="queueListener")
#Scope("singleton")
public Queue getQueue() {
return new Queue(MyConfig config);
}
}
Here is my Queue class -
public class Queue implements MessageListener{
private MyConfig config;
public Q(MyConfig config) {
this.config = config;
}
#Override
public void onMessage() {
createC();
}
public void createC() {
C cObj = config.getC();
cObj.setConfig(config);
cObj.performTask();
}
}
The class is "C" look like this-
public class C{
private transient MyConfig config;
private MyConfig config;
public C() {
}
public void setConfig(MyConfig config) {
this.config = config;
}
public MyConfig getConfig() {
return config;
}
public void performTask() {
A a = config.getA(); // Is it right way to get bean?
B b = config.getB();
}
}
So my question is that is it right way to get bean in another bean?
Will the return object really be spring bean object or simple java class object?
I can see cyclic reference in above code cause When instance of Queue class will be created inside MyConfig will take instance/reference of MyConfig.
Will this create cyclic reference?
My Architect has suggested me above approach instead of autoWiring Application context in both classes Queue and class "C". According to architect context is very heavy and it is not best practice.
What will be the execution cycle or call hierarchy when bean Queue is getting created?
It would be very much helpful to understand the working of above code.
It is a really bad idea to inject the configuration instance into a specific bean. It complicates your code and makes it inconvenient for testing because for testing Queue instance you should somehow mock the whole configuration.
If you want to inject a prototype bean to the singleton you can use a technique described here :
Howto generate prototype objects with in a singleton bean using spring java configurations
Please see example at Spring Boot #Autowired creating instances on a runtime
You can see how to use singleton and prototypes right way
I'm using Jersey 2 and Spring, and I'm trying to initialize my Jersey application (i.e. the class derived from ResourceConfig) with parameters from the Spring context.
Background: I have a single Jersey application that I build (i.e. a single WAR) and I deploy it across a server cluster with different Spring configurations on different servers to enable or disable different parts of the server, e.g. some of the servers have /search resources turned on, etc. This was really easy in Jersey 1.0: I just put,
<context:component-scan base-package="com.mycompany.resources.search"/>
in a Spring config to have Jersey scan that particular package and enable the JAX-RS resource providers in it.
Now in Jersey 2.0 the Spring <context:component-scan ... /> doesn't work, so resources have to be programmatically registered in a startup class derived from ResourceConfig:
public class MyApplication extends ResourceConfig {
public MyApplication() {
packages("com.mycompany.resources.search");
}
}
So far so good, but I need to conditionally scan that package, and I can't figure out how to get any Spring configuration into the MyApplication class. I thought that constructor injection might work:
public class MyApplication extends ResourceConfig {
#Autowired
public MyApplication(#Qualifier("my-config") MyConfiguration myConfiguration) {
if (myConfiguration.isEnabled()) {
packages("com.mycompany.resources.search");
}
}
}
However HK2 complains that it can't find a default constructor to use... so this indicates to me that DI is in play in the construction of this class, but that the DI isn't using Spring.
Similarly, using the the Spring bean lifecycle doesn't work:
public class MyApplication extends ResourceConfig implements InitializingBean {
#Autowired
private MyConfiguration myConfiguration;
public MyApplication() {
}
#Override
public void afterPropertiesSet() throws Exception {
if (myConfiguration.isEnabled()) {
packages("com.mycompany.resources.search");
}
}
}
(The afterPropertiesSet method isn't called.)
So now I'm stuck: is there any way to configure a Jersey ResourceConfig application object using Spring?
UPDATE:
I accepted #JohnR's answer below but I'll also include my eventual solution which I think is a bit cleaner. #JohnR's answer was to have the object initialized twice: first by Spring and then by Jersey/HK2. When Spring initializes the object you cache the dependencies in a static member, and then when Jersey/HK2 initializes it later you can retrieve the dependencies.
I ended up doing this:
public class MyApplication extends ResourceConfig {
public MyApplication() {
ApplicationContext rootCtx = ContextLoader.getCurrentWebApplicationContext();
MyConfiguration myConfiguration = rootCtx.getBean(MyConfiguration.class);
if (myConfiguration.isEnabled()) {
packages("com.mycompany.resources.whatever");
}
}
}
Rather than having the object initialized twice, we let Jersey/HK2 initialize it but then we retrieve the dependencies from Spring.
Both solutions are vulnerable to timing: they both assume that Spring is initialized before Jersey/HK2.
Expanding on my previous comment:
Trying to extend ResourceConfig is dangerous if you don't know what you're doing. Jersey becomes unpredictable, and if you try to subclass it into an Abstract class, Jersey crashes.
Instead, the JAX-RS specification provides us with a very useful interface called Feature: It allows you to register any classes you want as if you were configuring your own application. Furthermore, you don't need to use the awkward AbstractBinder, you just specify what contracts you register your classes with.
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
// Don't use #Component here, we need to inject the Spring context manually.
public class MySpringFeature implements Feature {
#Context
private ServletContext servletContext;
private ApplicationContext applicationContext;
#Autowired
private MySecurityDAO mySecurityDAO;
#Autowired
private MySpringResponseFilter myResponseFilter;
#Override
public boolean configure(FeatureContext context) {
if(this.servletContext == null) {
return false; // ERROR!
}
this.applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
if(this.applicationContext == null) {
return false; // ERROR!
}
// This is where the magic happens!
AutowireCapableBeanFactory bf = applicationContext.getAutowireCapableBeanFactory();
bf.autowireBean(this);
// From here you can get all the beans you need
// Now we take a Spring bean instance,
// and register it with its appropriate JAX-RS contract
context.register(myResponseFilter, ContainerResponseFilter.class);
// Or, we could do this instead:
SomeSecurityFilter mySecurityFilter = new SomeSecurityFilter();
mySecurityFilter.setSecurityDAO(mySecurityDAO);
context.register(mySegurityFilter, ContainerRequestFilter.class);
// Or even this:
SomeOtherSpringBean someOtherBean = applicationContext.getBean(SomeOtherSpringBean.class);
context.register(someOtherBean, SomeOtherJerseyContract.class);
// Success!
return true;
}
}
And in your ResourceConfig:
public class MyApplication extends ResourceConfig() {
public MyApplication() {
register(MySpringFeature.class);
}
}
Ta-da!
So now I'm stuck: is there any way to configure a Jersey
ResourceConfig application object using Spring?
I don't think you can configure Jersey to obtain your ResourceConfig from Spring as a Spring managed bean. It's a bit hackish, but you could do something like this. Note that you'll end up with two instance of your ResourceConfig: one managed by Spring and another by Jersey:
public class MyApplication extends ResourceConfig {
// static, available to all instances
private static MyConfiguration myConfiguration;
public MyApplication() {
// when Spring creates the first instance of MyApplication, myConfiguration
// will be null because the setter wasn't called yet
if (myConfiguration != null)
{
// second instance created by jersey... Spring will have autowired
// the first instance, and myConfiguration is static
if (myConfiguration.isEnabled())
packages("com.mycompany.resources.search");
}
}
#Autowired
public void setMyConfiguration(MyConfiguration config)
{
// instance level setter saves to a static variable to make it available for
// future instances (i.e. the one created by jersey)
MyApplication.myConfiguration = config;
}
}
Again, this is fairly hackish. You'll want to make sure Spring is initialized before Jersey and look closely at any threading issues that could occur during initialization.
I have a project where I have an interface, an Abstract class implementing the same interface and then a set of concrete classes which implement this interface and extend the Abstract Class.
public interface Invoice
{
void process();
}
#component
public abstract class AbstractInvoice(){
#Resource
protected Writer writer;
protected validateInvoice(){
//some implementation
}
}
#Component
public Class TypeAInvoice() extends AbstractInvoice implements Invoice{
#Override
public void process(){
//... some code
writer.write();
}
}
public Interface Writer(){
public void write();
}
#Component
public class CDWriter implements Writer{
#Override
public void write() { /* implementation.....*/}
}
Spring file has a component scan for the package.
<context:annotation-config>
<context:component-scan base-package="com.xyz" />
I am using a factory to get an instance of TypeAInvoice invoice
Now calling invoice.process() gets a NPE when getting to write.write()
I am not sure what am I missing here. I tried to see the component scan and scope and could not find anything conceptually wrong.
I am using a factory to get an instance of TypeAInvoice invoice
Depending on what your Factory does, this may be the problem. If the Factory creates a new TypeAInvoice, Spring wiring doesn't apply. You have to query the Spring context for the Bean. One way (though not very pretty) is to use ContextLoader:
return ContextLoader.getCurrentWebApplicationContext().getBean(TypeAInvoice.class)
I'd say static Factories and Spring don't go to well together. Spring stands for the Inversion of Control pattern, while Factories stand for the Service Locator pattern. I'd suggest that you get rid of your factories and autowire your Spring Beans.
Everything is good, except for the fact you use a factory to get the TypeAInvoice. If you create it like TypeAInvoice typer = new TypeAInvoice() then spring knows nothing of it, the Writer is not autowired, there for you get the NullPointerException. You should get the bean from the spring application context.
In my case, inside a Spring4 Application, i had to use a classic Abstract Factory Pattern(for which i took the idea from - http://java-design-patterns.com/patterns/abstract-factory/) to create instances each and every time there was a operation to be done.So my code was to be designed like:
public abstract class EO {
#Autowired
protected SmsNotificationService smsNotificationService;
#Autowired
protected SendEmailService sendEmailService;
...
protected abstract void executeOperation(GenericMessage gMessage);
}
public final class OperationsExecutor {
public enum OperationsType {
ENROLL, CAMPAIGN
}
private OperationsExecutor() {
}
public static Object delegateOperation(OperationsType type, Object obj)
{
switch(type) {
case ENROLL:
if (obj == null) {
return new EnrollOperation();
}
return EnrollOperation.validateRequestParams(obj);
case CAMPAIGN:
if (obj == null) {
return new CampaignOperation();
}
return CampaignOperation.validateRequestParams(obj);
default:
throw new IllegalArgumentException("OperationsType not supported.");
}
}
}
#Configurable(dependencyCheck = true)
public class CampaignOperation extends EO {
#Override
public void executeOperation(GenericMessage genericMessage) {
LOGGER.info("This is CAMPAIGN Operation: " + genericMessage);
}
}
Initially to inject the dependencies in the abstract class I tried all stereotype annotations like #Component, #Service etc but even though Spring context file had ComponentScanning for the entire package, but somehow while creating instances of Subclasses like CampaignOperation, the Super Abstract class EO was having null for its properties as spring was unable to recognize and inject its dependencies.After much trial and error I used this **#Configurable(dependencyCheck = true)** annotation and finally Spring was able to inject the dependencies and I was able to use the properties in the subclass without cluttering them with too many properties.
<context:annotation-config />
<context:component-scan base-package="com.xyz" />
I also tried these other references to find a solution:
http://www.captaindebug.com/2011/06/implementing-springs-factorybean.html#.WqF5pJPwaAN
http://forum.spring.io/forum/spring-projects/container/46815-problem-with-autowired-in-abstract-class
https://github.com/cavallefano/Abstract-Factory-Pattern-Spring-Annotation
http://www.jcombat.com/spring/factory-implementation-using-servicelocatorfactorybean-in-spring
https://www.madbit.org/blog/programming/1074/1074/#sthash.XEJXdIR5.dpbs
Using abstract factory with Spring framework
Spring and Abstract class - injecting properties in abstract classes
Inject spring dependency in abstract super class
Spring autowire dependency defined in an abstract class
Spring can you autowire inside an abstract class?
Please try using **#Configurable(dependencyCheck = true)** and update this post, I might try helping you if you face any problems.
So precisely my point here is you don't need to get a bean from spring context all the time.