【问题标题】:spring boot application - get bean from static contextSpring Boot 应用程序 - 从静态上下文中获取 bean
【发布时间】:2017-05-05 12:00:32
【问题描述】:

我有一个在 Spring 之外创建的类的实例,我希望能够访问 Spring bean,以便它可以触发事件并被 Spring bean 观察。我没有使用 Spring Web,我的应用程序是通过 Spring Boot 从命令行运行的。

【问题讨论】:

    标签: spring spring-boot


    【解决方案1】:

    您唯一的选择是使用静态方法公开应用程序的 Spring 上下文,以便不受 Spring 管理的对象可以使用它来获取对所需托管 bean 的引用。

    1. 从上下文的包装器开始。创建一个需要在其构造函数中引用上下文的常规托管 bean。引用被分配给一个静态类字段,该字段也有一个静态 getter:

      @Service
      class ContextWrapper {
      
          private static ApplicationContext context;
      
          @Autowired
          public ContextWrapper(ApplicationContext ac) {
              context = ac;
          }
      
          public static ApplicationContext getContext() {
              return context;
          }
      
      }
      
    2. 使用静态 getter 访问对象中不受 Spring 管理的上下文,并使用上下文中可用的方法获取对 bean 的引用:

      SomeBean bean = ContextWrapper.getContext().getBean("someBean", SomeBean.class);
      // do something with the bean
      
    3. 您需要的最后一件事是从 Spring bean 到非托管对象的通信通道。例如,SomeBean 可以公开一个 setter,它将接受非托管对象作为参数并将引用存储在字段中以供将来使用。对象 mast 使用上面提到的静态上下文访问器获取对托管 bean 的引用,并使用 setter 使 bean 知道它的存在。

      @Service
      class SomeBean {
      
          // ... your bean stuff
      
          private SomeClass someclass;
      
          public void setSomeClass(Someclass someclass) {
              this.someclass = someclass;
          }
      
          private void sendEventToSomeClass() {
              // communicate with the object not managed by Spring 
              if (someClass == null) return;
              someClass.sendEvent();
          }
      
      }
      

    【讨论】:

    • 如何确保上下文不为空或未完全加载?我可以相信 getContext() 会返回完整的 spring 上下文吗?为什么?
    • 如果您的 Spring 应用程序已经启动,则必须正确创建上下文。您唯一需要记住的是,您不应该在 bean 的构造函数中使用 getContext() 方法,因为 bean 构造是上下文创建的一部分。
    • 当从 常规(非 spring)类 调用获取 bean 时,我可以假设 spring 上下文已经开始了吗?是否需要添加检查/功能以确保 spring 上下文不为空或未完全加载?
    【解决方案2】:

    您可以通过构造函数注入 spring bean,例如:

    @Service
    class Bean {
        ...
    }
    
    class NotBean {
    
          private Bean bean;
    
          public NotBean(Bean bean) {
           this.bean = bean;
          }
    
          // your stuff (handle events, etc...)
    }
    

    【讨论】:

    • 我无法控制另一个 NotBean 的实例化方式,因此,我不能简单地将 bean 引用传递给它...
    • 你能从那个 NotBean 扩展吗?
    猜你喜欢
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2017-02-14
    • 2021-02-06
    相关资源
    最近更新 更多