簡體   English   中英

如何構建和連接Spring數據庫依賴項.JAR項目以與多個.WAR項目一起使用?

[英]How to build and wire Spring database dependency .JAR project for use with multiple .WAR projects?

我正在構建一套Web服務,它們都訪問同一數據庫,但使用不同的憑據。 因此,為了使數據庫代碼模塊化,我將其移出每個Web應用程序.WAR文件,並給數據庫調用其自己的.JAR文件。 這樣,如果WebApp1和WebApp2使用getAllColumnsFromTable1 MyBatis調用,則不必在兩個項目中都定義相同的映射器和域對象。 這樣,只要Table1發生更改,我只需要在一個位置更改MyBatis代碼,並減少復制和粘貼錯誤。

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使用的數據源。

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中的一項服務中添加類似的內容

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方面,我有

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>

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設置才能使所有這些協同工作,還是我要以一種完全錯誤的方式來解決這個問題?

您似乎缺少TableMapper bean的Spring配置。 該類必須是Spring Bean,才能將其注入Service 將相關的Bean配置添加到applicationContext.xml

Spring上下文層次結構可以在常見的代碼場景中提供幫助。 如果單個EAR中有多個Web應用程序,則EAR可以具有自己的上下文,該上下文是各個Webapp上下文的父級。 同樣在每個Web應用程序中,您也可以有一個根上下文和單個子上下文。 您可以在web.xml中定義此層次結構。 可以通過上下文參數指定父上下文:locatorFactorySelector和parentContextKey。 通過上下文參數contextConfigLocation(servlet外部)根上下文。 子上下文可以在每個servlet的init參數-上下文參數中指定。

在EAR中有一個jar保存所有公共服務和DAO層代碼,並在beanRefContext.xml(基本上是另一個應用程序上下文xml)中定義它們。 使此jar在classpath中可用。

在每個要引用父上下文代碼的應用程序的web.xml中:

    <!--  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如下所示:

    <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>

這樣,您將實現您想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM