繁体   English   中英

Spring + Vaadin集成设计模式

[英]Spring + Vaadin integration design patterns

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

我们到目前为止找到的选项是:

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

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

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

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

GitHub上有一个演示它如何工作的演示

将弹簧与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);
 }
}

在使用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服务类。

3)Vaadin应用程序servlet启用了load-on-startup。 实际的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()并正常使用它。

如今,事实上的方法是使用官方的Vaadin Spring集成库。 这使得UI类Spring管理bean并提供了方便的Vaadin相关范围。 然后,您可以根据您的要求决定您希望制作Spring bean的UI代码中有多少帮助程序类。 至少考虑制作例如所有Views Spring管理。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM