My code is like this:
interface MyIntreface{
...
}
class A implements MyInterface{}
class B implements MyInterface{}
class BaseClass{
#Inject
MyInterface instance;
}
class MyFirstClass extends BaseClass{
....
}
class MySecondClass extends BaseClass{
....
}
Now I want to MyFirstClass have implementation A and MySecondClass implementation B. #Named annotations seems not to work in this case. Is there any other robo-solution ?
This use case is impossible to implements using Roboguice. But there are two ways to resolve your problem.
Implement provider that injects MyFirstClass and MySecondClass and then inject to provider A or B and use setter to set it in created instance
class Baclass BaseClass{
protected abstract MyInterface extractMyInterface();
}
class MyFirstClass extends BaseClass{
#Inject
B instance;
protected MyInterface extractMyInterface() {
return instance;
}
}
class MySecondClass extends BaseClass{
#Inject
A instance;
protected MyInterface extractMyInterface() {
return instance;
}
}
In my opinion the first one (with Provider) is much more cleaner.
Related
I am using the Spring/Springboot framework and would like to know if there is a possibility to "choose" or "select" the implementation class to instanciate depending on a configuration parameter
Let's say I have an interface IMyInterface and two possible implementations IImplentation1 and IImplementation2
I also have a class FooBar whose constructor receives a configuration class MyConf and an instance of IMyInterface
#Component
interface IMyInterface {
}
class IImplentation1 implements IMyInterface {
}
#Component
class IImplentation2 implements IMyInterface {
}
#Component
#ConfigurationProperties("my.application")
#Validated
class MyConf {
String kind; /// could be an enum
}
class IImplentation2 implements IMyInterface {
}
#Component
class FooBar {
#Autowired
public FooBar(MyConf myConf,
IMyInterface myInterface) { /// IImplentation1 or IImplentation2
... /// depending on MyConf.kind
}
}
Thanks for help
Regards
Philippe
I have an interface, and there are some implementations for this. Each implementation belongs to some type.
I want that when I'm using autowired I would able to get all the implementation of the certain type. How can I do it?
public interface someInterface{}
public class impl1OfType1 implements someInterface{}
public class impl2OfType1 implements someInterface{}
public class impl1OfType2 implements someInterface{}
public class impl2OfType2 implements someInterface{}
public class someClass{
#autowired
public someClass(List<someInterface> interfaceList){}
}
I want to get only impl1OfType1 and impl2OfType1. And not all the implementation.
And at other place I want to get only impl1OfType2 and impl2OfType2.
more concrete example -
public interface EntityCreator{
createEntity();
}
#Component
public class DogCreator implements entityCreator{}
#Component
public class CatCreator implements entityCreator{}
#Component
public class CarCreator implements entityCreator{}
#Component
public class TruckCreator implements entityCreator{}
#Component
public class AnimalsFactory{
#Autowired
public AnimalsFactory(List<EntityCreator> creators){}
}
The solution would be using #Qualifier.
#Component
#Qualifier("place1")
class Impl1OfType2 implements SomeInterface {}
#Component
#Qualifier("place1")
class Impl2OfType2 implements SomeInterface {}
#Service
class SomeClass {
#Autowired
public SomeClass(#Qualifier("place1") List<SomeInterface> interfaceList) {
System.out.println(interfaceList);
}
}
I slightly changed the names to adhere to the Java convention. They are still a bit awkward and contextless.
UPDATE
You might use generics, Spring is good at dealing with them. For instance, it will inject only DogCreator and CatCreator into a List<EntityCreator<Animal>>.
interface Animal {}
interface Machine {}
interface EntityCreator<T> {}
#Component
class DogCreator implements EntityCreator<Animal> {}
#Component
class CatCreator implements EntityCreator<Animal> {}
#Component
class CarCreator implements EntityCreator<Machine> {}
#Component
class TruckCreator implements EntityCreator<Machine> {}
#Component
class AnimalsFactory {
#Autowired
public AnimalsFactory(List<EntityCreator<Animal>> creators) { }
}
UPDATE 2
You could write marker interfaces which would break down existing implementations into logical groups.
interface AnimalCreator {}
interface EntityCreator<T> {}
#Component
class DogCreator implements EntityCreator, AnimalCreator {}
#Component
class CatCreator implements EntityCreator, AnimalCreator {}
#Component
class AnimalsFactory {
#Autowired
public AnimalsFactory(List<AnimalCreator> creators) {
System.out.println(creators);
}
}
If you correct your code with above comments and I understand your problem, I assume this can be a way to solve your issue.
public interface Someinterface<T extends someType> {}
public class someType{}
public class Type1 extends someType{}
public class Type2 extends someType{}
public class TypedInterface1 implements Someinterface<Type1> {}
public class TypedInterface2 implements Someinterface<Type2> {}
public class someClass{
#Autowired
public someClass(List<TypedInterface1> interfaceList){}
}
Let me know if I answered your question.
I have an interface like this:
#Local
public interface MyInterface {
}
And two classes that implements this interface:
#Singleton
public class FirstBean implements MyInterface {
}
#Singleton
public class SecondBean implements MyInterface {
}
And another class like below:
#Singleton
public class ThirdBean {
#EJB
private MyInterface xpto;
}
And i am receiving the following error on deploy:
More than one ejb found with interface of type for binding
How to solve it?
Try to use qalifier
#java.lang.annotation.Documented
#java.lang.annotation.Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.METHOD, ElementType.TYPE,ElementType.FIELD})
#javax.inject.Qualifier
public #interface First {
}
Mark bean using this qualifier
#Singleton
#First
public class FirstBean implements MyInterface {
}
Then inject it
#Singleton
public class ThirdBean {
#Inject
#First
private MyInterface xpto;
}
I had an issue to autowire an object in my abstract base class. It always give me null instead of an instance. Please help.
Base class:
public abstract class BaseClass implements IReq<Req> {
#Autowired
protected ReqDao dao;
protected void updateReq() {
dao.update();
}
}
Child class:
#Component
public class ChildClass extends BaseClass {
...
}
ReqDao class:
#Component
public class RptRequestDao {
public void update(){
...
}
}
I am thinking of simply use the update() function in Base class, which means in my ChildClass, I don't override that one. Is this the problem? If it is, what's the normal way to do it? Thanks in advance.
A bean is created on demand, in your case when you initialize your object,
RepoDao is private so it wont be inhereted to the class which will be intialized, you either need to put
#Component
public class ChildClass extends BaseClass {
#Autowired
private ReqDao dao;
or make it protected/public in BaseClass, sure public will make it accessible to other classes which violates the encapsulation
Instantiate your child class using #Autowired like this
public class SomeClass{
#Autowired
ChildClass childClass; //IMPORTANT
}
The error occurs when you try to instantiate the childClass like this:
public class SomeClass{
ChildClass childClass = new ChildClass();
}
BaseClass is abstract you can't instantiate it.You need to have your ReqDao in ChildClass to be autowired.Spring will only autowire when it will create an instance of that class.Hope that helps
Check how you are instantiating the child class. Make sure you are NOT using "new" keyword to instantiate child class.
ChildClass cc = new ChildClass() // **Not recommended**
You must autowire the childclass and let spring take care of bean creation.
Is it posible to build a common DAO class for different beans/tables?
Currently I am creating different DAO classes for each different table like: CustomerDAO, EmployeeDAO, StudentDAO.
Yes it is possible.
How ?
This is Base DBO class for all your CustomerDBO, EmployeeDBO, StudentDBO.
public class BaseDBO {
}
Now, each of your DBO will be like this,
public class CustomerDBO extends BaseDBO {}
public class EmployeeDBO extends BaseDBO {}
public class StudentDBO extends BaseDBO {}
Write all the common methods in BaseDAO like
public class BaseDAO<T extends BaseDBO> {
void create(T t){}
void update(T t){}
void delete(T t){}
}
Now on specific DAO looks like
CustomerDAO,
public class CustomerDAO extends BaseDAO<CustomerDBO> {
}
Now, for CustomerDAO contains all the methods which are common for DAO.
Similarly for StudentDAO, EmployeeDAO.
Hope this helps !!