【问题标题】:Spring-Roo: How to retrieve component instance dinamically by name or id?Spring-Roo:如何通过名称或 id 动态检索组件实例?
【发布时间】:2016-02-12 10:12:24
【问题描述】:

我有一个用@Component 和@Service 注释的类。从 beans 容器中获取此类实例的常用方法是使用 @Reference:

@Reference private MyClass myclass;

如何使用字符串键检索实例,就像我们在 Spring Web 应用程序中使用 ApplicationContext 一样?我试过 ComponentContext.locateService 但我不知道这是否正确也不知道我必须使用哪个键值。

MyClass myclass = (MyClass)context.locateService("????"); //Which is the way?

我编辑了我的问题,我会尽力解释得更好。 我有这样的课:

@Component
@Service
class MySvcImpl implements MySvc { ... }

以这种方式注入:

class Main {
   @Reference private MySvc svc;

   void method1(){
       svc.doXXX();
   }
}

在这种情况下,我只有一个班级。我想要一堆组件子类(MySvcSubX),以便我可以根据参数使用它们中的任何一个。据称,我不再需要 @Reference 行了。

@Component
@Service
class MySvcSub1Impl extends MySvcImpl implements MySvc { ...}    
//The same with MySvcSub2Impl, 3, and so forth

然后在我的主课中:

void method1(String key){
    MySvc svc = callToLocateBeanById(key);
}

我不需要为每个子类添加一个引用,以便能够通过它们的名称找到它们。

【问题讨论】:

    标签: java osgi spring-roo


    【解决方案1】:

    给你:

    ApplicationContext context = new ClassPathXmlApplicationContext(
                "classpath*:mySpringConfig.xml");
    MyClass myClassBean =  (MyClass) context.getBean("myClass");
    

    【讨论】:

    • 如果我正确理解了这个问题,它与osgi declarated-services有关,而不是spring。但我不知道为什么会有一个 spring-roo 标签 :-)
    • spring-roo 标签是因为我正在开发一个插件。 Spring Roo 插件使用 OSGi 功能,Roo shell 使用 osgi 命令安装它们。
    【解决方案2】:

    您可以发布带有属性的@Component

    @Component(property="type=xxx")
    public class MyComponent implements MySvc {
    
    }
    

    然后在此属性上使用过滤器查询 osgi 注册表:

    BundleContext bc = ..;
    Collection<ServiceReference<MySvc>> ref = bc.getServiceReferences(MySvc.class, "(type=xxx)")
    // check cardinality, etc
    MySvc svc = bc.getService(ref);
    // use svc
    bc.ungetService(ref);
    

    如果您在编译时(或通过某些配置)知道要查找的密钥,则可以注入带有目标的引用:

    @Reference(target = "(type=xxx)")
    private MySvc component;
    

    旧答案

    您应该使用引用的名称。这个名字可以在@Reference中指定,但是默认是从属性的名字生成的,或者bind/unbind方法(这个注解见javadoc)

    在你的例子中,它应该是:

    MyClass myclass = (MyClass)context.locateService("myClass");
    

    如果您不确定,可以查看组件中生成的 xml,您会看到生成的名称。

    【讨论】:

    • 谢谢,我会试试的,但我不确定这是否是我想要的。我已经扩展了我的问题文本来解释这一点。
    • 最后添加的问题对我来说没有任何意义。你能试着用不同的方式解释吗?
    • 您好 Jerémie,您的方法有效,但正如我所说,我认为这不是我想要的。还是谢谢。
    • 听起来不错。我会试着告诉你。谢谢!
    猜你喜欢
    • 2018-12-13
    • 1970-01-01
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    相关资源
    最近更新 更多