如何构建和关联Spring数据库依赖项.JAR项目以与多个.WAR项目一起使用? [英] How to build and wire Spring database dependency .JAR project for use with multiple .WAR projects?

查看:87
本文介绍了如何构建和关联Spring数据库依赖项.JAR项目以与多个.WAR项目一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一套Web服务,这些服务都可以访问同一数据库,但是使用不同的凭据.因此,为了使数据库代码模块化,我将其移出每个Web应用程序.WAR文件,并给数据库调用其自己的.JAR文件.这样,如果WebApp1和WebApp2使用getAllColumnsFromTable1 MyBatis调用,则不必在两个项目中都定义相同的映射器和域对象.这样,如果Table1发生更改,我只需要在一个位置更改MyBatis代码,并减少复制和粘贴错误.

I am building a suite of web services that all access the same database but using different credentials. So to modularize the database code I am moving it out of each web app .WAR files and giving the database calls its own .JAR file. So that if WebApp1 and WebApp2 use a getAllColumnsFromTable1 MyBatis call I don't have to define the same mapper and domain object in both projects. That way I only have to change the MyBatis code in one place if Table1 ever changes, and less copy and paste mistakes.

WebApp1 applicationContext.xml:

WebApp1 applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

  <context:annotation-config />

  <context:component-scan base-package="com.example.webapp1.service" />
  <context:component-scan base-package="com.example.webapp1.controller" />

  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:/example/ds/WebApp1DS" />
  </bean>

  <bean id="databaseConnector" class="com.example.databaseconnector.connector"
    <property name="dataSource" ref="dataSource" />
  </bean>
</beans>

所以我要传递给数据库连接器.JAR文件的只是.WAR正在使用的数据源.

So what I want to pass to the database connector .JAR file is just the data source that the .WAR is using.

WebApp1 pom.xml:

WebApp1 pom.xml :

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>WebApp1</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>3.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>3.2.3.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>com.example</groupId>
      <artifactId>databaseconnector</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>
</project>

然后在.WAR中的一项服务中有类似的内容

Then have something like this in one of the services in the .WAR

WebApp1 Service.java:

WebApp1 Service.java:

package com.example.webapp1.service;

import com.example.databaseconnector.domain.TableSearchResult;
import com.example.databaseconnector.persistence.TableMapper;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class Service {
  @Autowired
  private TableMapper tableMapper;

  public List<TableSearchResult> getSearchResults(String param) {
    return tableMapper.getAllColumnsFromTable1(param);
  }
}

然后在.JAR方面

数据库连接器pom.xml:

databaseconnector pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
                             http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>databaseconnector</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>Database Connector</name>

  <dependencies>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.2.3</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.2.1</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.0.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.0.0.RELEASE</version>
    </dependency>
  </dependencies>
</project>

数据库连接器DatabaseConnection.java:

databaseconnector DatabaseConnection.java:

package com.example.databaseconnector.connector;

import javax.sql.DataSource;

import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

public class DatabaseConnection implements InitializingBean {
  private DataSource dataSource;
  private DataSourceTransactionManager dataSourceTransactionManager;
  private SqlSessionFactoryBean sqlSessionFactoryBean;
  private MapperScannerConfigurer mapperScannerConfigurer;

  public DataSource getDataSource() {
    return this.dataSource;
  }

  public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    if (getDataSource() == null) {
      throw new IllegalArgumentException("Property 'dataSource' is required");
    } else {
      this.configureDataSourceTransactionManager();
      this.configureSqlSessionFactoryBean();
      this.configureMapperScannerConfigurer();
    }
  }

  private void configureDataSourceTransactionManager() {
    this.dataSourceTransactionManager = new DataSourceTransactionManager();

    this.dataSourceTransactionManager.setDataSource(dataSource);
  }

  private void configureSqlSessionFactoryBean() {
    this.sqlSessionFactoryBean = new SqlSessionFactoryBean();

    this.sqlSessionFactoryBean.setDataSource(dataSource);

    this.sqlSessionFactoryBean.setConfigLocation(
        new ClassPathResource("mybatis-config.xml"));

    this.sqlSessionFactoryBean.setTypeAliasesPackage(
        "com.example.sewp5databaseconnector.domain");
  }

  private void configureMapperScannerConfigurer() {
    this.mapperScannerConfigurer = new MapperScannerConfigurer();

    this.mapperScannerConfigurer.setBasePackage(
        "com.example.databaseconnector.persistence");

    this.mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean");
  }
}

当我运行WebApp1时,程序失败,因为它找不到TableMapper bean来自动装配服务中的映射器.我错过了什么Spring设置才能使这些全部协同工作,还是我要以一种完全错误的方式来解决这个问题?

When I run WebApp1 the program fails because it could not find the TableMapper bean to autowire the mapper in the service. What Spring setup am I missing to get this to all work together, or am I going about this the completely wrong way?

推荐答案

Spring上下文层次结构可以在常见的代码场景中提供帮助. 如果单个EAR中有多个Web应用程序,则EAR可以具有自己的上下文,该上下文是各个Webapp上下文的父级. 同样在每个Web应用程序中,您也可以有一个根上下文和单个子上下文. 您可以在web.xml中定义此层次结构.可以通过上下文参数指定父上下文:locatorFactorySelector和parentContextKey.通过上下文参数contextConfigLocation(servlet外部)根上下文.子上下文可以在init参数中指定-每个servlet的context参数.

Spring context hierarchy can help in common code scenario. If you have multiple webapps in a single EAR, EAR can have its own context, which is the parent of the individual webapp contexts. Also in each webapp, you can have one root context and individual children context as well. You can define this hierarchy in web.xml. Parent context can be specified through context parameters: locatorFactorySelector and parentContextKey. Root context through context parameter contextConfigLocation(outside servlet). Child context can be specified in the init param - context parameter of each of the servlet.

在EAR中有一个jar来存放所有公共服务和DAO层代码,并在beanRefContext.xml(基本上是另一个应用程序上下文xml)中定义它们.使这个jar在classpath中可用.

Have one jar in EAR holding all your common service and DAO layer code and define them in beanRefContext.xml(which is basically another application context xml). make this jar available in classpath.

每个要引用父上下文代码的应用程序的web.xml中:

In web.xml of each app where you want to refer parent context code:

    <!--  root application context -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:rootContextBeans.xml</param-value>
    </context-param>
    <!--  shared service layer - parent application context -->
    <context-param>
        <param-name>locatorFactorySelector</param-name>
        <param-value>classpath:beanRefContext.xml</param-value>
    </context-param>
    <context-param>
        <param-name>parentContextKey</param-name>
        <param-value>servicelayer-context</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>     
    <servlet>
        <servlet-name>dispatcherServletApp1</servlet-name> 
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
        <init-param> 
            <param-name>contextConfigLocation</param-name> 
            <param-value>classpath*:webApp1.xml</param-value> 
        </init-param> 
    </servlet> 

其中的beanRefContext.xml类似于:

where beanRefContext.xml will be like:

    <beans>
      <bean id="servicelayer-context" class="org.springframework.context.support.ClassPathXmlApplicationContext">
        <constructor-arg>
          <list>
            <value>data-layer-context.xml</value>
          </list>
        </constructor-arg>
      </bean>
    </beans>

这样,您将实现自己想要的.

This way you will achieve what you want.

这篇关于如何构建和关联Spring数据库依赖项.JAR项目以与多个.WAR项目一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆