Spring:通过ApplicationContext访问主bean

发布于 2024-12-11 08:13:55 字数 152 浏览 0 评论 0原文

如果我的 ApplicationContext 中有 2 个 bean 实现相同的接口,我可以在 bean 定义中将其中一个标记为主要 bean。该 bean 更适合依赖注入。

有没有一种方法可以使用 ApplicationContext 直接访问主应用程序而不需要 DI?

If I have 2 beans in my ApplicationContext implementing the same interface I can mark one of them as primary in the bean definition. This bean is prefered for dependency injection.

Is there a way to get direct access using the ApplicationContext to the primary one without DI?

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

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

发布评论

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

评论(3

过期以后 2024-12-18 08:13:55

有许多不同的方法可以做到这一点。

  1. 在主 bean 定义中设置 Primary="true"。设置此值后,如果有多个自动布线候选者,则主要者将获得更高的优先级。

    <豆子...>
      />
      >
     
    
  2. 或者,如果您认为该 Bean 根本不应该自动连接到任何 Bean,则为非主 Bean 设置 autowire-candidate="false"。但是,在定义具有相同接口的另一个 bean 时需要小心,如果忘记添加它,将会再次出现多个主 bean。

    <豆子...>
      />
      
        
    
  3. 通过使用命名依赖项使自动连接注释更加具体,可以使用 @javax.annotation.Resource 注释进行归档,如下所示。这将降低确定可以注入哪个 bean 的代码复杂性,因为我们可以简单地通过 id 定位 bean。

    @Resource(name="myPrimaryBeanId")
    受保护的 MyInterface myInstance;
    

非依赖注入 (DI) 方法

如果您不喜欢使用 DI,则可以使用以下方法从 ApplicationContext 中按名称获取 bean

MyInterface myInstance = (MyInterface) 
    applicationContext.getBean("myPrimaryBeanId");

如果您想使用非 DI 方法,而是从 spring 中进行操作bean,如果您没有 spring 上下文的句柄来执行此操作,您可以更改您的类以实现 org.springframework.context.ApplicationContextAware 接口,这将要求您实现 setApplicationContext(ApplicationContext)方法,spring 会将句柄注入到当前应用程序上下文中,如下所示。

public class MyBean implements ApplicationContextAware {

  private ApplicationContext applicationContext;

  private String MY_PRIMARY_BEAN_ID = "myPrimaryBeanId";

  public void myMethod() {
    MyInterface myInstance = getMyPrimaryBean();

    // do my logic here
  }

  private MyInterface getMyPrimaryBean() {
    return (MyInterface) applicationContext.getBean(MY_PRIMARY_BEAN_ID);
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext)
      throws BeansException {
    this.applicationContext = applicationContext;
  }

}

注意:此答案基于 Spring 2.5.x

There are many different ways to do this.

  1. Set primary="true" in the primary bean definition. When this is set, if there are multiple candidates for auto wiring, the primary will be given the higher priority.

    <beans ...>
      <bean id="myPrimaryBeanId" class="mypackage.MyInterface" primary="true"/>
      <bean id="mySecondaryBeanId" class="mypackage.MyInterface" />
    </beans> 
    
  2. Alternatively, set autowire-candidate="false" for the non primary beans, if you think this bean should not be auto wired in to any bean at all. However, need to be careful when defining another bean with the same interface, as if you forget to add this, there will again be multiple primary beans.

    <beans ...>
      <bean id="myPrimaryBeanId" class="mypackage.MyInterface"/>
      <bean id="mySecondaryBeanId" class="mypackage.MyInterface"
          autowire-candidate="false"/>
    </beans>    
    
  3. Be more specific on the auto wiring annotations by using named dependencies, which can be archvied by using @javax.annotation.Resource annotation as shown below. This will reduce the code complexity of figuring out which bean could have been injected, as one can simply locate the bean by id.

    @Resource(name="myPrimaryBeanId")
    protected MyInterface myInstance;
    

Non Dependency Injection (DI) method

If you prefer not to use DI, you can use the following to fetch the bean by name from the ApplicationContext

MyInterface myInstance = (MyInterface) 
    applicationContext.getBean("myPrimaryBeanId");

If you want to do with non DI method, but from a spring bean, and if you do not have a handle to the spring context to do it, you can change your class to implement the org.springframework.context.ApplicationContextAware interface, which will require you to implement the setApplicationContext(ApplicationContext) method, in to which spring will inject the handle to the current application context as shown below.

public class MyBean implements ApplicationContextAware {

  private ApplicationContext applicationContext;

  private String MY_PRIMARY_BEAN_ID = "myPrimaryBeanId";

  public void myMethod() {
    MyInterface myInstance = getMyPrimaryBean();

    // do my logic here
  }

  private MyInterface getMyPrimaryBean() {
    return (MyInterface) applicationContext.getBean(MY_PRIMARY_BEAN_ID);
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext)
      throws BeansException {
    this.applicationContext = applicationContext;
  }

}

Note: This answer is based on Spring 2.5.x

一个人练习一个人 2024-12-18 08:13:55

首先你需要 BeanFactory/ApplicationContext。例如,您可以通过实现 BeanFactoryAware 来检索它。假设它是 ConfigurableListableBeanFactory,您可以检查给定类型的主要内容,如下所示:

  ConfigurableListableBeanFactory clbf =
        (ConfigurableListableBeanFactory)beanFactory;
  String[] beanNames = clbf.getBeanNamesForType(myType);
  for (String beanName : beanNames) {
     BeanDefinition bd = clbf.getBeanDefinition(beanName);
     if (bd.isPrimary()) {
        ...
     }
  }

First you need your BeanFactory/ApplicationContext. You can retrieve it for example by implementing BeanFactoryAware. Assuming it is ConfigurableListableBeanFactory, you can check what's primary for given type like this:

  ConfigurableListableBeanFactory clbf =
        (ConfigurableListableBeanFactory)beanFactory;
  String[] beanNames = clbf.getBeanNamesForType(myType);
  for (String beanName : beanNames) {
     BeanDefinition bd = clbf.getBeanDefinition(beanName);
     if (bd.isPrimary()) {
        ...
     }
  }
掩耳倾听 2024-12-18 08:13:55

只需将其声明为 Bean 并通过从 ApplicationContext 获取并设置它来手动设置依赖关系。但你会打破控制反转

Just declare it as Bean and set the dependency manually by fetching from ApplicationContext and setting it . But you will break Inversion of Control

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