【问题标题】:Getting Spring Application context from a non bean object without using Singleton不使用 Singleton 从非 bean 对象获取 Spring Application 上下文
【发布时间】:2010-10-03 07:28:31
【问题描述】:

我需要从非 bean 对象中获取 spring 应用程序上下文。在 SO 的另一个线程中,接受的答案建议使用单例来获取应用程序上下文。 Getting Spring Application Context

但是使用单例使我的代码更加耦合且可测试性更低,这是许多线程中讨论的常见问题(例如What is so bad about Singletons

问题是,有没有一种优雅的方法可以在不使用单例的情况下从非 bean 对象获取应用程序上下文?

【问题讨论】:

    标签: design-patterns spring singleton


    【解决方案1】:

    我认为您的问题与我几天前遇到的问题差不多。我认为以下内容应该适合您:

    首先创建一个名为AppContextManager 的类,如下所示:

    @Component
    public class AppContextManager implements ApplicationContextAware{
        private static ApplicationContext _appCtx;
    
        @Override
        public void setApplicationContext(ApplicationContext ctx){
             _appCtx = ctx;
        }
    
        public static ApplicationContext getAppContext(){
            return _appCtx;
        } 
    }
    

    @Component注释上面的类或在application context xml中为AppContextManager声明一个bean。

    现在在您的 non-singleton non-spring 实例中使用以下代码 sn -p 获取任何其他 春豆:

    ApplicationContext ctx = ApplicationContextManager.getAppContext();
    SomeSpringBean bean = ctx.getBean(SomeSpringBean.class);
    

    这将为您提供代码中任何位置的 bean 实例。

    【讨论】:

    • 您是否为 AppContextManager 正确创建了 bean。您的 bean 应该位于由 component scan base package 配置定义的包中,或者在您的应用程序上下文 xml 中声明一个相同的 bean。
    • @mickeymoon 感谢您的回答,这对我很有帮助。
    • 我认识到这是一个非常古老的问题,但我已经多次看到这个解决方案,但我不确定它应该如何工作。如果在你的 NON SPRING 类中你有一个 ApplicationContext 类型的对象,那么你一定有一个 Spring 依赖,不是吗?否则不能调用 getBean 方法。
    • 效果很好,谢谢!如果您的派生类结构能够负担得起(或常见的单例),您可以在这个基类中@Autowire 组件/bean
    【解决方案2】:

    总是存在引导问题。对于 Web 应用程序,通常有处理这种情况的外部 servlet 过滤器。

    如果不是网络应用程序,则无法绕过某种外部单例或引导程序。但;在此处使用单例应该只会影响该单个引导程序类的可测试性。您的代码中应该只有很少的地方需要以任何显式方式引用容器。所以它并没有真正显着增加耦合。

    或者换种说法,实际上应该只有非常少的非 bean 对象需要访问 spring 容器。如果不是这种情况,那么您可能没有以最佳方式使用弹簧。大多数/所有需要容器的人可能应该只实现BeanFactoryAwareApplicationContextAware

    【讨论】:

    • 对此+1。在您的应用程序代码中通常应避免使用单例。对于某些类型的引导程序或基础设施,这没什么大不了的。很可能你不需要对你的引导程序进行单元测试。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多