CDI injecting Bean which has parameterised constructor - cdi

I have a class A which is kind of a wrapper over class B just to make B Serializable. Now I have class C in which I need to inject class A to be instantiated with attributes 'a' and 'b'. How can this be achieved?
The following is my code:
Class A extends B {
public A(int a, int b){
super(a,b);
}
class C{
#Inject
A objA; //will not work
}

Generally, its a good design practice not to pass data through constructor for injectable services. make your services as stateless and reusable as much as possible.
If that's not possible, you can check on CDI producer semantics here: Using producer methods and Fields

I think I agree with maress in that you're probably doing something fundamentally wrong, but without your entire use case, I'll offer the following:
Your class A, as it stands, cannot be injected into C because it is not a CDI bean. In order to be a CDI bean, it must have either a no-arg constructor or a constructor annotated with #Inject.
In this case, even if you annotate your constructor with #Inject:
#Inject
public A(int a, int b) { ... }
You still will not be able to inject A into C. The problem is that there many ways to satisfy that constructor. The container will not know which ints you mean to inject. That is, did you want it to instantiate an A(0,0) or an A(1,2) or an A(-12, 5001) or ... ?
You have a few options. You can use a qualifier (such as #Named) to disambiguate the particular ints that you want to inject:
#Inject
public A(#Named("int1") int a, #Named("int2") int b) {...}
The qualified ints can be generated via a producer method:
#Produces #Named("int1")
public int get_int1() { return 5; }
#Produces #Named("int2")
public int get_int2() { return 6; }
Alternately, you could use a producer method to produce instances of your A:
#Produces
public A get_A() { return new A(5,6); }

Related

Call #Autowire bean through Mockito

I have Class A and Class B. B is autowired in class A. Now I want to test the flow using mockito.
So the problem is when I tried to mock the class A and B in my test case using #InjectMock its going to class A but its not invoking class B.
I dont want to mock the class B which is autowired in class A, from A its should make call to class B and get the user details data.
#Component
public class A {
#Autowired
private B b;
public Users getUsers() {
Long id = 10;
b.getUserDetails(id);
// some Logic
}
}
#Component
public class B {
public UserDetails getUserDetails(Long id) {
// some logic to get users details ..
}
}
#RunWith(MockitoJUnitRunner.class)
public class TestA {
#InjectMocks
private A a;
#InjectMocks
private B b;
#Test
public void testA() {
Users actual = a.getUsers();
assertEquals(actual, expected());
assertNotNull(actual);
}
private Users expected() {
return new Users(); // expected users object
}
}
You should use #Spy on B in order to use real B class
#Spy
private B b;
the spy will wrap an existing instance. It will still behave in the same way as the normal instance – the only difference is that it will also be instrumented to track all the interactions with it.
You should change #InjectMocks annotation on above B to #Spy and you should add #Spy on above A also. Because you want to use B.class's and A.class's real methods. Why you need to use #Spy ?
If you use #Mock, by default for all methods, mock returns null, an empty collection or appropriate primitive / primitive wrapper value (e.g. 0, false, null, ...)
If you use #Spy then the real methods are called (unless a method was stubbed).
As a result, your creation in TestA.class should be like :
#Spy #InjectMocks private A a;
#Spy private B b;

Is there any way to mock field of Class

Here's my case, I have a class A which has one member field b. And I want to test and in unit test, I mocked A and also need to call method f() which will invoke b's f(). But the b variable in mocked A is null, so will throw NPE, and I have no get/set method for b, so is there any way to mock b ? THanks
public static class B{
public void f() {
}
}
public static class A {
B b;
public void f() {
b.f();
}
}
If you want to mock out the b property of A in a test, you've given the b property default (package-private) access, so as long as your test is in the same package you could replace the b property directly.
#Test
public void testB() {
A underTest = new A();
B mockedB = Mockito.mock(B.class);
underTest.b = mockedB;
underTest.f();
Mockito.verify(mockedB).f();
}
As an aside, I personally dislike using package-private access to mess around with member properties for tests, and instead would recommend a dependency injection framework like Guice or Spring DI for constructor injection.
However you've described that you've mocked out A, I'd have thought if this was the case the f() method of A would do nothing - you wouldn't get a null pointer exception as the call to the mock will replace the real b property and just be a void method that does nothing. Please can you provide more details if this is the case?

Factory pattern with CDI depending on runtime parameter

I wanted to implement the factory pattern with CDI. Here we have the business case example:
A client provides a string representing a type. Depending on this type the factory returns an implementation of an interface.
I know that there are a lot of questions flying around concerning factory pattern and CDI. The difference I have here is that I resolve the implementation returned by the factory based on a runtime parameter.
I was thinking of using a producer method but then I can not think of how to inject the resolved implementation into the bean where the implementation is needed since this is a runtime parameter which is not necessarily known at contruction time.
So I thought of the pretty straight forward way of using the Instance class.
Here is the basic implementation :
// the interface. Instances of this class are returned from the factory
public interface Product {
}
// one implementation may be returned by the factory
#ProductType("default")
public class DefaultProduct implements Product {
}
// another implementation may be returned by the factory
#ProductType("myProduct")
public class MyProduct implements Product {
}
// the qualifier annotation
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.FIELD, ElementType.TYPE})
public #interface ProductType {
String value();
}
// the Annotation implementation to select
// the correct implementation in the factory
public class ProductTypeLiteral extends AnnotationLiteral<ProductType>
implements ProductType {
private String type;
public ProductTypeLiteral(String type) {
this.type = type;
}
#Override
public String value() {
return type;
}
}
// the factory itself. It is annotated with #Singleton because the
// factory is only needed once
#Singleton
public class Factory {
#Inject
#Any
private Instance<Product> products;
public Product getProduct(String type) {
ProductTypeLiteral literal = new ProductTypeLiteral(type);
Instance<Product> typeProducts = products.select(literal);
return typeProducts.get();
}
}
In my opinion using Instance is very sophisticated.
But this has one major drawback:
Everytime you cal the Instance.get() method you retrieve a new Instance of Product. This may be fine but the Instance instance keeps a reference of the returned instance internally. So as long as the Factory lives and each time the Instance.get() is called the more instances of Product will exist in the memory and never get garbage collected because a reference is still hold in Instance.
I thought of not making the Factory a singleton but that just shifts the problem and does not solve it. And of course it is against the factory pattern.
Another solution I tried was to iterate through the Instance instead of selecting an implementation with the help of the annotation:
#Singleton
public class Factory {
#Inject
#Any
private Instance<Product> products;
public Product getProduct(String type) {
Product product = null;
for(Product eachProduct : products) {
ProductType productType = eachProduct.getClass().
getAnnotation(ProductType.class)
if(productType.value().equals(type) {
product = eachProduct;
break;
}
}
return product;
}
}
Basically this is working. Now each time depending on the given type I retrieve the same instance of Product. That way the memory is not consumed.
But I don't like it to iterate over a collection when I have the possibility to resolve the correct implementations more elegantly.
Do you have any ideas which may solve the problem? Otherwise I may have to keep the iteration solution.
Herein lies your problem. Instance keeps reference to instances you obtain from it using get() because it is responsible for reclaiming them when they go out of scope (i.e. when the injected Instance goes out of scope. But because you made your factory a singleton, it will never go out of scope. So, make your factory a short-lived scope, like #RequestScoped or even #Dependent, that way all the returned instances will be reclaimed properly.
Maybe it can help you:
Create qualifiers:
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface MyProduct{
}
#Qualifier
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public #interface DefaultProduct{
}
In Factory class:
#Singleton
public class Factory {
public Product getProduct(#MyProduct MyProduct product, #DefaultProduct DefaultProduct defaultProduct) {
//What you wanna do
}
}

groovy: variable scope in closures in the super class (MissingPropertyException)

I have the impression that closures run as the actual class being called (instead of the implementing super class) and thus break when some variables are not visible (e.g. private in the super class).
For example
package comp.ds.GenericTest2
import groovy.transform.CompileStatic
#CompileStatic
class ClosureScopeC {
private List<String> list = new ArrayList<String>()
private int accessThisPrivateVariable = 0;
void add(String a) {
list.add(a)
println("before ${accessThisPrivateVariable} ${this.class.name}")
// do something with a closure
list.each {String it ->
if (it == a) {
// accessThisPrivateVariable belongs to ClosureScopeC
accessThisPrivateVariable++
}
}
println("after ${accessThisPrivateVariable}")
}
}
// this works fine
a = new ClosureScopeC()
a.add("abc")
a.add("abc")
// child class
class ClosureScopeD extends ClosureScopeC {
void doSomething(String obj) {
this.add(obj)
}
}
b = new ClosureScopeD()
// THIS THROWS groovy.lang.MissingPropertyException: No such property: accessThisPrivateVariable for class: comp.ds.GenericTest2.ClosureScopeD
b.doSomething("abc")
The last line throws a MissingPropertyException: the child class calls the "add" method of the super class, which executes the "each" closure, which uses the "accessThisPrivateVariable".
I am new to groovy, so I think there must be an easy way to do this, because otherwise it seems that closures completely break the encapsulation of the private implementation done in the super class ... this seems to be a very common need (super class implementation referencing its own private variables)
I am using groovy 2.1.3
I found this to be a good reference describing how Groovy variable scopes work and applies to your situation: Closure in groovy cannot use private field when called from extending class
From the above link, I realized that since you have declared accessThisPrivateVariable as private, Groovy would not auto-generate a getter/setter for the variable. Remember, even in Java, private variables are not accessible directly by sub-classes.
Changing your code to explicitly add the getter/setters, solved the issue:
package com.test
import groovy.transform.CompileStatic
#CompileStatic
class ClosureScopeC {
private List<String> list = new ArrayList<String>()
private int accessThisPrivateVariable = 0;
int getAccessThisPrivateVariable() { accessThisPrivateVariable }
void setAccessThisPrivateVariable(int value ){this.accessThisPrivateVariable = value}
void add(String a) {
list.add(a)
println("before ${accessThisPrivateVariable} ${this.class.name}")
// do something with a closure
list.each {String it ->
if (it == a) {
// accessThisPrivateVariable belongs to ClosureScopeC
accessThisPrivateVariable++
}
}
println("after ${accessThisPrivateVariable}")
}
}
// this works fine
a = new ClosureScopeC()
a.add("abc")
a.add("abc")
// child class
class ClosureScopeD extends ClosureScopeC {
void doSomething(String obj) {
super.add(obj)
}
}
b = new ClosureScopeD()
b.doSomething("abc")
There is a simpler way, just make the access modifier (should rename the property really) to protected, so the sub-class has access to the property.. problem solved.
protected int accessThisProtectedVariable
To clarify on your statement of concern that Groovy possibly has broken encapsulation: rest assured it hasn't.
By declaring a field as private, Groovy is preserving encapsulation by intentionally suspending automatic generation of the public getter/setter. Once private, you are now responsible and in full control of how or if there is a way for sub-classes (protected) or all classes of objects (public) to gain access to the field by explicitly adding methods - if that makes sense.
Remember that by convention, Groovy ALWAYS calls a getter or setter when your codes references the field. So, a statement like:
def f = obj.someField
will actually invoke the obj.getSomeField() method.
Likewise:
obj.someField = 5
will invoke the obj.setSomeField(5) method.

Replacing factory class with CDI

I have a collection of Processor beans in my application along with a factory for creating them.
public abstract class Processor {
public Processor(String config) { .... }
public abstract void process() throws Exception;
}
public class Processor1 extends Processor {
public Processor1(String config) { super(config);..}
public void process() {....}
}
public Processor newProcessor(String impl, String config) {
// use reflection to create processor
}
Can I use CDI to replace the factory class/method? And instead use a #Produces?
I tried using the following to iterate or select the instance I wanted. But Weld tells me that allProcessorInstances.isUnsatisfied() == true. I had to create default no-args ctor in order for Weld to find my Processor subclasses.
#Inject #Any Instance<Processor> allProcessorInstances;
Is there any way to tell the CDI container to use the constructor I want it to use? Or am I thinking about this problem the wrong way?
To use the constructor you'd need to annotate it with #Inject, however, every param on the constructor must itself be a bean or something in the CDI scopes.
Using a producer method and having that take an InjectionPoint as a param, then having your configuration be part of an annotation would work.

Resources