【问题标题】:How to inject ApplicationContext itself如何注入 ApplicationContext 本身
【发布时间】:2011-06-22 06:57:49
【问题描述】:

我想将 ApplicationContext 本身注入到 bean 中。

类似

public void setApplicationContext(ApplicationContect context) {
  this.context = context;
}

春天可以吗?

【问题讨论】:

    标签: java spring applicationcontext


    【解决方案1】:

    以前的cmets还可以,但我通常更喜欢:

    @Autowired private ApplicationContext applicationContext;
    

    【讨论】:

    • +1 顺便说一句,您对通过直接@Autowired 注入 applicationContext 或实现 ApplicationContextAware 接口之间的利弊有任何想法吗?谢谢。
    • @Bariscan:我认为没有优缺点。但我更喜欢这个,因为@Autowired 是我用来注入所有属性的东西,所以为什么要做不同的事情只是因为它是一个ApplicationContext?
    • 你能提供一个更详细的@Autowired(我是一个大粉丝)应用程序上下文的例子吗?对我来说总是空的。需要什么额外的接口吗?谢谢。
    • @Autowired 是否在同一个 bean 中注入其他属性?在 Spring 3.1.1 中,完全相同的代码适用于我。
    • 虽然我同意@Autowired 很好;当涉及到循环引用时,使用 @Autowired 和 ApplicationContextAware 之间的差异可能会非常惊人。事实证明,简单地删除@Autowired就解决了我在circular-dependency-in-spring中描述的问题
    【解决方案2】:

    很简单,使用ApplicationContextAware 接口。

    public class A implements ApplicationContextAware {
      private ApplicationContext context;
    
      public void setApplicationContext(ApplicationContext context) {
          this.context = context;
      }
    }
    

    然后在你实际的 applicationContext 中你只需要引用你的 bean。

    <bean id="a" class="com.company.A" />
    

    【讨论】:

      【解决方案3】:

      是的,只需实现ApplicationContextAware -interface。

      【讨论】:

        【解决方案4】:

        我在上面看到了一些关于 @Autowired 仍然无法正常工作的 cmets。以下可能会有所帮助。

        这不起作用:

        @Route(value = "content", layout = MainView.class)
        public class MyLayout extends VerticalLayout implements RouterLayout {
        
          @Autowired private ApplicationContext context;
        
           public MyLayout() {
            comps.add(context.getBean(MyComponentA.class)); // context always null :(
        }
        

        你必须这样做:

         @Autowired
          public MyLayout(ApplicationContext context) {
            comps.add(context.getBean(MyComponentA.class)); //context is set :)
        }
        
        

        或者这个:

        
        @PostConstruct
            private void init() {
            comps.add(context.getBean(MyComponentA.class)); // context is set :)
        }
        

        还要注意,Upload 是另一个必须在@PostConstruct 范围内设置的组件。这对我来说是一场噩梦。希望这会有所帮助!

        我几乎忘了提到 @Scope 注释可能对您的 Bean 是必需的,如下所示。在 Bean 中使用 Upload 时就是这种情况,因为 UI 在创建 Bean 之前没有实例化/附加,并且会导致抛出空引用异常。使用@Route 时不会这样做,但使用@Component 时会这样做 - 所以后者不是一个选项,如果@Route 不可行,那么我建议使用@Configuration 类来创建具有原型范围的bean。

        @Configuration
        public class MyConfig {
          @Bean
          @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
          public MyComponentA getMyBean() {
            return new MyComponentA();
          }
        }
        

        【讨论】:

          【解决方案5】:

          特殊解决方案:从任何(非 Spring)类中获取 Spring bean

          @Component
          public class SpringContext {
              private static ApplicationContext applicationContext;
          
              @Autowired
              private void setApplicationContext(ApplicationContext ctx) {
                  applicationContext = ctx;
              }
          
              public static <T> T getBean(Class<T> componentClass) {
                  return applicationContext.getBean(componentClass);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-02-27
            • 1970-01-01
            • 2023-03-07
            • 2012-03-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多