如何使用@Autowired像工厂模式一样动态注入实现

发布于 11-02 19:58 字数 1664 浏览 7 评论 0原文

我对 Sprint 相当陌生,我的应用程序使用 Spring 3.x 和 roo1.1.1。

我有一个接口的多个实现,该接口将 @Autowired 到其他不同的类中。我只能在运行时决定采用哪种实现。这应该通过类似工厂模式来实现。

public interface SomeInterface {
    public void doSomething();
}

实现 1.

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

实现 2.

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

现在,在我的服务中,我需要这个 Autowired,例如

@Service 
public class MyService {

   @Autowired
   SomeInterface ob;
   //Rest of the code here

}

1) 选择要 Autowired 的实现的逻辑仅在运行时知道,因此我无法使用 @Qualifier 注释来限定它。 2)我尝试创建一个像

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;
}
}

在 applicationContext.xml 中提到的标签一样的 FactoryBean 。

当我运行网络服务器时,我遇到了一个错误,比如

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

任何人都可以帮我解决这个问题吗?如果我没有正确执行此操作,请指导我以正确的方式执行此操作。

感谢并感谢任何帮助, 杰杰克

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

I have multiple implementation of an interface which would be @Autowired into other different classes. I would only be able to decide which implementation to go with at the runtime. This should be achieved with like a 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 needed this Autowired like

@Service 
public class MyService {

   @Autowired
   SomeInterface ob;
   //Rest of the code here

}

1) The logic to choose which implementation to be Autowired is only know runtime, so i cannot use the @Qualifier annotation to qualify this.
2) I tried to create a FactoryBean like

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;
}
}

In the applicationContext.xml i have the tag mentioned.

When i run the webserver i run into 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 please help me to resolve this issue. If i am not doing this right please direct me to do this the right way.

Thanks and appreciate any help,
jjk

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

茶花眉2024-11-09 19:58:56

谢谢你的建议。我在同事的帮助下解决了这个问题。我做错了什么,

  1. 我用@Service 实现了SomeInterface。所以这被弹簧扫描仪拾取并添加到 bean 中。
  2. 在试验和错误期间,我从 FactoryBean 实现中删除了 @Component 注释。

进行这些更改后,它就像魅力一样发挥作用。

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

  1. I had the implementation of the SomeInterface with @Service. So this was picked up by the spring scanner and added to the bean.
  2. During trial and error i removed the @Component annotation from by FactoryBean implementation.

After making these changes it worked like a charm.

半窗疏影2024-11-09 19:58:56

如果您只需要应用程序的给定实例的 bean 的一种实现,则从 isSingleton() 返回 true

但我质疑您的设计。

我总是使用属性文件来切换这样的实现。我曾经不得不为一个网站实施验证码集成。我们使用 JCaptcah 和 ReCAPTCHA API 进行原型设计。我创建了一个新接口,其中仅包含我们需要的功能,然后为这两个 API 创建了实现。使用 Spring 配置文件和 Maven 配置文件中的占位符,我们可以在编译时或部署时切换实现类,例如 mvn jetty:run -DcaptchaImpl=recaptcha 或 -DcaptchaImpl=jcaptcha。

如果不知道您想要完成的任务,就很难提供更多建议。

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

But I question your design.

I would always use properties files to switch out implementations like this. I once had to implement CAPTCHA integration for a site. We were prototyping with the JCaptcah and ReCAPTCHA APIs. I created a new interface that contained just the functionality we needed and then created implementations for both APIs. Using a placeholders in the Spring configuration file and Maven profiles, we could switch out the implementation class at compile time or deployment time, for example, mvn jetty:run -DcaptchaImpl=recaptcha or -DcaptchaImpl=jcaptcha.

Without knowing the task that you want to accomplish, it's hard to provide more advice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文