Reputation: 2613
I have a java interface say ITest implemented by two classes Class1 and Class2. Now I have a factory class which I use to decide which implementation to return. like
if(something)
return new Class1()
else
return new Class2()
Problem is that I have autowired field in Class1 which doesn't get instantiated,, but the same autowiring works in other classes which were instantiated via autowiring.
Here is code for Class1
@Componene
public Class1 implements ITest{
@Autowired
private SomeClass obj;
}
Not sure how to get around this problem. As autowiring for SomeClass works fine in Other classes.
Upvotes: 1
Views: 6976
Reputation: 80
I would suggest to use @value annotation for this scenario.
Example
MyClass{
Object getObjectFromFactory()
{
if(something)
return new Class1()
else
return new Class2()
}
}
then you can use it like below
@Value("#{MyClass.getObjectFromFactory}")
private Object myObject;
Upvotes: -1
Reputation: 106
It strongly depends of what exactly do you need, but you can:
Then whole magic is done by Spring
If you just want to switch between two different stateless implementations you can inject both of them to factory and return an existing bean
@Compoment class Factory {
@Autowired
Class1 class1Instance;
@Autowired
Class2 classInstance;
...
if(something)
return class1Instance;
else
return class2Instance;
...
}
}
But please make sure that both injected classes have no state.
Make factory managed by Spring, both classes not-managed by Spring and inject dependencies manually:
public Class1 implements ITest{
private SomeClass obj;
public Class1(SomeClass obj) {
this.obj=obj;}
}
and in factory:
@Autowired
private SomeClass obj;
...
if(something)
return new Class1(obj);
else
return new Class2(obj);
At first glance looks strange, by that way you can e.g. separate domain and application/infrastructure parts.
Upvotes: 1
Reputation: 53
You could use your Main Configuration class which is annotated with @SpringBootApplication or @Configuration.
Example:
@SpringBootApplication
public class YourApp {
public static void main(String[] args) {
SpringApplication.run(YourApp.class, args);
}
@Autowired
private CsvBeanRepository repo;
@Bean
public InterfaceSome some() {
if(something) {
return new Some(repo);
} else {
return new Some2(repo);
}
}
}
inside a @SpringBootApplication class or a @Configuration class you can @Autowire your classes normally and use them as parameters for your factory.
Upvotes: 0
Reputation: 2168
Inject applicationContext in your factory class and use it for bean creation:
@Autowired private ApplicationContext applicationContext;
......
......
if(something){
return applicationContext.getBean("com.xyz.Class1");
}
......
......
OR you can use @Configurable
on top of Class1 and Class2. This needs AspectJ weaving to be enabled. Spring will then magically create beans when you use new.
Upvotes: 1