How to use @Autowired to dynamically implement an implementation, like a factory pattern

I am new to Sprint and am using Spring 3.x and roo1.1.1 for my application.

I have several implementations of an interface that will be @Autowired in other classes. I could only decide which implementation to work with at runtime. This should be achieved using the factory pattern.

public interface SomeInterface { public void doSomething(); } 

Implementation 1.

 public class SomeOb implements SomeInterface { public void doSomething() { //Do something for first implementation here } } 

Implementation 2.

 public class SomeOtherOb implements SomeInterface { public void doSomething() { //Do something for first implementation here } } 

Now in my service I need this Autwired, as

 @Service public class MyService { @Autowired SomeInterface ob; //Rest of the code here } 

1) The logic of choosing which implementation should be Autowired is to only know the runtime, so I cannot use the @Qualifier annotation to qualify it. 2) I tried to create a FactoryBean, for example

 public class SomeFactoryBean implements FactoryBean<SomeInterface> { @Override public SomeInterface getObject() throws Exception { if(/*Somecondition*/) { return new SomeOb(); } else return new SomeOtherOb(); } @Override public Class<? extends SomeInterface> getObjectType() { if(/*Somecondition*/) { return SomeOb.class; } else return SomeOtherOb.class; } @Override public boolean isSingleton() { return false; } } 

A tag is specified in applicationContext.xml.

When I start the web server, I run an error like

 No unique bean of type [com.xxxx.xxxx.SomeInterface] is defined: expected single matching bean but found 3: [xxxx, xxxxxxx, xxxxFactory] 

Can anyone help me solve this problem. If I don’t do it right, ask me to do it right.

Thanks and appreciate any help, JJK

+5
spring autowired
source share
2 answers

Thanks for the suggestion. I was able to solve the problem with the help of a colleague. What i did wrong

  • I had an implementation of SomeInterface with @Service. So it was found using the spring scanner and added to the bean.
  • During trial and error, I removed the @Component annotation using the FactoryBean implementation.

After making these changes, it worked like a charm.

+3
source share

returns true from isSingleton () if you need only one bean implementation for a given instance of your application

But I doubt your design.

I would always use property files to disable such implementations. Once I had to implement CAPTCHA integration for a site. We prototyped with the JCaptcah and ReCAPTCHA APIs. I created a new interface containing only those functions that we need, and then created implementations for both APIs. Using placeholders in the Spring configuration file and Maven profiles, we can disable the implementation class at compile time or deployment time, for example mvn jetty: run -DcaptchaImpl = recaptcha or -DcaptchaImpl = jcaptcha.

Without knowing the tasks you want to complete, it is difficult to provide more advice.

0
source share

All Articles