是否有一种方法可以在Spring应用程序中静态/全局地请求ApplicationContext的副本?

假设主类启动并初始化了应用程序上下文,它是否需要通过调用堆栈向下传递给任何需要它的类,或者类是否有一种方法来请求先前创建的上下文?(我假设它必须是单例的?)


当前回答

方法1:您可以通过实现ApplicationContextAware接口来注入ApplicationContext。参考链接。

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

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

方法2:在任何spring托管bean中自动装配应用程序上下文。

@Component
public class SpringBean {
  @Autowired
  private ApplicationContext appContext;
}

参考链接。

其他回答

在Spring bean中进行自动装配,如下所示:

@Autowired
private ApplicationContext appContext;

您将得到ApplicationContext对象。

如果你使用的是web应用,还有另一种不使用单例的方式来访问应用上下文,那就是使用servletfilter和ThreadLocal。在过滤器中,您可以使用WebApplicationContextUtils访问应用程序上下文,并在TheadLocal中存储应用程序上下文或所需的bean。

警告:如果你忘记撤消ThreadLocal,你将在尝试撤消应用程序时遇到严重的问题!因此,您应该设置它,并立即开始尝试,在最后部分取消对ThreadLocal的设置。

当然,这仍然使用一个单例:ThreadLocal。但实际的豆子不需要再这样了。它甚至可以是请求范围的,如果应用程序中有多个war,并且EAR中的库也可以使用此解决方案。不过,您可能会认为ThreadLocal的这种使用与普通单例的使用一样糟糕。;-)

也许Spring已经提供了类似的解决方案?我没有找到,但我不确定。

方法1:您可以通过实现ApplicationContextAware接口来注入ApplicationContext。参考链接。

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

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

方法2:在任何spring托管bean中自动装配应用程序上下文。

@Component
public class SpringBean {
  @Autowired
  private ApplicationContext appContext;
}

参考链接。

在Spring应用程序中有许多获取应用程序上下文的方法。这些因素如下:

通过ApplicationContextAware: 进口org.springframework.beans.BeansException; 进口org.springframework.context.ApplicationContext; 进口org.springframework.context.ApplicationContextAware; 公共类AppContextProvider实现了ApplicationContextAware { private ApplicationContext; @Override setApplicationContext(ApplicationContext)抛出BeansException { 这一点。applicationContext = applicationContext; } }

这里setApplicationContext(ApplicationContext ApplicationContext)方法将获得ApplicationContext

ApplicationContextAware: 接口,由希望被通知的任何对象实现 它运行的ApplicationContext的。实现此接口 例如,当一个对象需要访问一组 合作bean。

通过Autowired的: @ autowired private ApplicationContext;

这里@Autowired关键字将提供applicationContext。自动连线有一些问题。这将在单元测试时产生问题。

在你执行任何其他建议之前,问自己这些问题…

为什么我要获取ApplicationContext? 我是否有效地使用ApplicationContext作为服务定位器? 我可以完全避免访问ApplicationContext吗?

在某些类型的应用程序(例如Web应用程序)中,这些问题的答案比在其他应用程序中更容易,但无论如何都值得一问。

访问ApplicationContext确实违反了整个依赖注入原则,但有时您没有太多选择。