【问题标题】:Spring + Vaadin integration design patternsSpring + Vaadin集成设计模式
【发布时间】:2011-12-29 12:47:48
【问题描述】:

将 spring 与 vaadin/gwt 集成时使用了哪些设计模式?我们在我们的应用程序中使用 spring 和 hibernate,每个 dao 都是一个 spring bean。问题是在 Vaadin 方面使用它们的最佳方式是什么?

目前我们发现的选项有:

  • 制作所有 vaadin 控件 spring bean(有时可能很难......,使用原型范围等)
  • 使用编译时编织 - 但是编译需要几分钟时间,在每次更改后运行 maven install 非常烦人
  • 加载时间编织似乎与 atomikos 冲突
  • 创建一些 bean 管理器,它已自动装配所有需要的 daos 并像在单例中一样返回其实例

【问题讨论】:

    标签: spring integration vaadin


    【解决方案1】:

    试试我的Spring Stuff Vaadin Add-On,​​它有一些有用的类用于集成 Vaadin 和 Spring。

    有一个demo on GitHub 显示它是如何工作的。

    【讨论】:

      【解决方案2】:

      我建议使用 Vaadin UIProvider 机制。 这种方式在 UI 中自动装配是完全透明的。

      您可以在 github 上查看使用此解决方案的一个非常简单的示例:spring-vaadin-example

      【讨论】:

        【解决方案3】:

        在使用了 Vaadin 和 Spring 之后,我们决定将 Spring bean 仅用于 DAO 类,其中 PersistenceContext 注入非常非常方便。所有其他类,包括但不限于 Vaadin 控件,都是“普通”类,没有 Spring 对其进行控制。

        做出该决定后,实际问题变成了“我们如何在非 Spring 相关代码中获得启用 Spring 的 DAO?”我们选择了一种“刚刚好”且麻烦最少的快速而简单的解决方案。

        0) 向 web.xml 添加了两个 Spring 监听器和一个过滤器:

        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
        </listener>
        
        <filter>
            <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
            <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
        </filter>
        
        <filter-mapping>
            <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
            <servlet-name>BlahBlah Application</servlet-name>
        </filter-mapping>
        

        1) 为所有 Spring 管理的服务 bean 创建一个应用程序范围的占位符:

        public class DAO {
            private static Logger log = Logger.getLogger(DAO.class);
        
            private static BlahBlahService blahBlahService;
            private static AnotherService anotherService;
        
            public static final void initialize(ApplicationContext context) {
                log.info("DAO initializing...");
                blahBlahService = context.getBean( BlahBlahService.class );
                anotherService = context.getBean( AnotherService.class );
            }
        
            public static BlahBlahService getBlahBlahService() {
                return blahBlahService;
            }
            public static AnotherService getAnotherService() {
                return anotherService;
            }
        }
        

        2) 通常通过@Service 原型注解声明 Spring-service 类。

        3) Vaadin 应用程序 servlet 启用了启动时加载。实际的 init() 方法执行以下操作:

        @Override
        public void init( ServletConfig config ) throws ServletException {
            Logger.getLogger( InitServlet.class ).info( "init()..." );
        
            super.init( config );
        
            WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( config.getServletContext() );
        
            DAO.initialize( wac );
        }
        

        4) 应用程序代码必须调用 DAO.getThisOrThatService() 并正常使用它。

        【讨论】:

          【解决方案4】:

          将 spring 与 vaadin/gwt 集成时使用了哪些设计模式?

          与上面提供的内容略有不同。它对我有用,而且非常简单,所以我把它贴在这里。

          我在 web.xml 中添加了以下内容,并使用了对依赖项的 spring-context 的精确类路径引用(更改路径以满足您的需要):

          <!-- Spring context loader -->
          <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>      
          </listener>
          <context-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:com/company/appserv/spring/spring-context.xml</param-value>
           </context-param>
          

          以上假设您已将 spring-web 添加到您的 pom.xml,因此请务必这样做。您还需要 servlet-api。因此,您将在 pom 中添加以下内容,调整版本以满足您的需求:

          <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
          </dependency>
          <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
          </dependency>
          

          现在,创建以下类:

          import com.vaadin.Application;
          import com.vaadin.terminal.gwt.server.WebApplicationContext;
          import javax.servlet.ServletContext;
          import org.springframework.context.ApplicationContext;
          import org.springframework.web.context.support.WebApplicationContextUtils;
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          
          public class SpringContextHelper {
          
          private ApplicationContext context;
          
          private static Logger logger = LoggerFactory.getLogger(SpringContextHelper.class);
          
          public SpringContextHelper(Application application) {
              ServletContext servletContext = ((WebApplicationContext) application.getContext()).getHttpSession().getServletContext();
              context = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
              logger.debug("Number of beans: {}",context.getBeanDefinitionCount());
          }
          
          public Object getBean(final String beanRef) {
              return context.getBean(beanRef);
          }    
          }
          

          现在创建您的 DAO 类(如之前的帖子中所建议的那样):

          import com.company.appserv.dbo.DatabaseHelper;
          import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;
          import com.vaadin.Application;
          
          public class DAO {
          
          private static DatabaseHelper databaseHelper;
          
          private static Logger logger = LoggerFactory.getLogger(DAO.class);
          
          public static final void initialize(Application application) {
              logger.debug("DAO initializing...");
              if (databaseHelper == null) {
                  logger.debug("Creating databaseHelper...");
                  SpringContextHelper helper = new SpringContextHelper(application);
                  databaseHelper = (DatabaseHelper)helper.getBean("databaseHelper");
              }
          }
          
          public static DatabaseHelper getDatabaseHelper() {
              return databaseHelper;
          }
          }
          

          最后,请务必初始化您现在将在各种视图类中使用的 DAO。这个初始化将发生在你扩展Application的任何类中,如下所示:

          import com.vaadin.Application;
          import com.vaadin.ui.Window;
          
          /**
           * The Application's "main" class
           * 
           * Vaadin framework associates requests with sessions so that 
           * an application class instance is really a session object.
           */
          @SuppressWarnings("serial")
          public class VoucherTool extends Application
          {
            private Window mainWindow;
          
            @Override
            public void init() {
              mainWindow = new Window("Application");
              setMainWindow(mainWindow);
          
              // Needed because composites are full size
              mainWindow.getContent().setSizeFull();
          
              LoginView myComposite = new LoginView();
              mainWindow.addComponent(myComposite);
              setTheme("applicationtheme");
          
          DAO.initialize(this);
           }
          }
          

          【讨论】:

            【解决方案5】:

            这些天事实上的方法是使用官方的Vaadin Spring 集成库。这使得 UI 类 Spring 托管 bean 并提供方便的 Vaadin 相关范围。然后,您可以根据您的要求决定您希望在 UI 代码中创建多少个帮助器类来制作 Spring bean。至少考虑制作例如Spring 管理的所有视图。

            start.spring.io 服务包含一个添加相关 Vaadin Spring 依赖项的选项,然后只需创建 UI 类并使用 @SpringUI 注释对其进行注释。无需单独创建 VaadinServlet。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-09-27
              • 1970-01-01
              • 1970-01-01
              • 2018-06-09
              • 1970-01-01
              • 2017-10-10
              • 1970-01-01
              相关资源
              最近更新 更多