【问题标题】:Spring: how to get hold of Application context in Webapp and Standalone programSpring:如何在 Webapp 和独立程序中获取应用程序上下文
【发布时间】:2012-07-25 20:09:44
【问题描述】:

我是 Spring 框架的新手。我们想在web应用中引入它(3.1),目前在web层使用struts,在业务层使用service facades和business objects,在持久层使用自己写的JDBC DAO(都是紧密耦合的!)

我创建了几个 .xml 配置,一个用于 servlet 配置,只扫描 com.mydomain.web 包。另一个在服务层 appContext-service.xml 扫描 com.mydomain.bs 和 .bo 包,一个用于 DAO 层 appContext-persistence.xml 扫描 .dao 包。

我们有四个具有适当项目依赖关系的 Eclipse 项目:Web、Business、Common(包含域对象、DTO、异常等)、DataAccess。

我想在可能的情况下使用注释,并且已经创建了一个 MVC 控制器、一个带有接口的新服务和一个带有接口的新 dao,使用 JDBC 模板,这一切都很好。

现在我的问题是:

  1. 我们不能一次重写所有代码,我们在这里讨论的是更大的代码库。但是,当新创建的服务也需要来自(尚未)Spring 感知的服务和业务对象时,我该怎么办?它们不是 bean,也不是由 Spring 创建的。我将如何获得我的服务 bean?

  2. 我们有几个独立的应用程序用于批处理、定期清理文件系统和数据库表等。它们由 cron (UNIX cron) 触发,因此有自己的 JVM。考虑到不同的 .xml 配置,我如何在这里最好地使用 Spring 服务?

  3. 我的设置是否有意义?

感谢您的任何见解。

【问题讨论】:

    标签: java spring spring-mvc architecture


    【解决方案1】:
    1. 让 spring 处理所有 bean 的生命周期是很常见的,否则可能会有点棘手。不是 Spring bean 的对象有望在某处初始化。使该初始化程序成为 Spring bean 并使其具有应用程序上下文意识

       public class SpringContextHolder implements ApplicationContextAware {
      
         private static ApplicationContext applicationContext = null;
      
          public static ApplicationContext getApplicationContext() {
              return applicationContext;
          }
          public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
               this.applicationContext = applicationContext;
          }
          public void init(){
      
              ServiceBean1 srv1 = (ServiceBean1)applicationContext.getBean("serviceBean1");
      
              myNonSpringObject.setService1(srv1); // Or something
          }
      }
      
    2. 设置一个独立的 spring 应用程序非常简单。只需创建一个 Spring XML 并连接您的 bean(通过扫描/注释或 XML)。不建议在 main 方法中执行此操作,但您可以轻松找出如何在独立应用程序中获取此设置。请记住,您的应用程序本身不应该真正做太多的生命周期逻辑,而是让 Spring 来做。

      public class StandaloneSpringApp{
        public static void main(String[] args){
          ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
      
          SomeBeanType bean = (SomeBeanType)ctx.getBean("SomeBeanName");
          bean.doProcessing(); // or whatever
        }
      
      }
      
    3. 您的设置非常合理,即使我无法可视化您的整个范围,但您的方法是大型模块化 spring 应用程序的良好起点。

    【讨论】:

    • 1.在我的例子中,bean 是一个像 ProductBO 这样的业务对象,它是使用 new MyBO(); 创建的。我现在想知道,从 BO 调用服务是否是一个好主意,阅读关于业务逻辑和业务实体分离的不同意见。据我了解,Spring 不负责创建域实体或业务对象,是吗?
    • 2.所以我根本不会使用我的 appContext-service.xml 和 appContext-persistence.xml 并为批处理应用程序编写一个新的 appContext.xml?。
    • 3.谢谢。事实上,我不确定我的架构的细节:我有一个像 ProductBO 这样的缓存(手动在 ConcurrentHashMap 中)。 Producer(一个简单的实体,在应用程序的不同位置使用)还有另一个缓存。现在 ProductBO 有一个生产者,但是因为生产者被缓存了,所以我不想硬连线这两个,因为生产者可以改变(创建它的一个新实例,具有相同的 ID)。因此,只有 producerID 存储在 ProductBO 中,并且使用 ProducerService 应请求从缓存中加载 Producer。
    猜你喜欢
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2016-12-04
    • 2012-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多