一、創建 SSMVCAnnoDemo 項目
點擊菜單,選擇“File -> New Project” 創建新項目。選擇使用 archetype 中的 maven-quickstart 模版創建。
輸入對應的項目坐標GroupId 和 ArtifactId
之后在項目名稱中填入項目名稱,這里我填的 ProjectName 和上文的 ArtifactId 相同,都是 SuperDemo。
點擊確定后,等待 Maven 幫我們構建好項目的目錄結構。當控制台顯示 BUILD SUCCESS 就表示初始化完成了。
完成初始化之后,我們分別創建 model、interface、provider、consumer 模塊,它們的作用分別是:
model:存放 POJO 文件的模塊
interface:存放接口文件的模塊
provider:提供服務的模塊
consumer:調用服務的模塊
二、配置 model 模塊
在 SuperDemo 模塊的 pom.xml 文件添加 JUnit、Log4J 等公共依賴:
<!-- 單元測試 JUnit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>provided</scope> </dependency> <!-- 日志記錄 Log4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.6</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.6</version> </dependency> <!-- JSON 包 --> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency>
修改后的 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.chanshuyi.SuperDemo</groupId> <artifactId>SuperDemo</artifactId> <version>1.0-SNAPSHOT</version> <modules> <module>interface</module> <module>model</module> <module>provider</module> <module>consumer</module> </modules> <packaging>pom</packaging> <name>SuperDemo</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <junit.version>3.8.1</junit.version> </properties> <dependencies> <!-- 單元測試 JUnit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>provided</scope> </dependency> <!-- 日志記錄 Log4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.6</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.6</version> </dependency> <!-- JSON 包 --> <dependency> <groupId>net.sf.json-lib</groupId> <artifactId>json-lib</artifactId> <version>2.4</version> <classifier>jdk15</classifier> </dependency> </dependencies> </project>
下載 MBGGenerator(密碼:c1dy),這是MyBatis 官方的 MyBatis Generator,我們使用它將數據庫表轉化成 model、mapper 以及 SqlProvider 文件。
下載文件解壓放到 provider 模塊的 resources 目錄下。進入 resources/mbg 目錄,雙擊運行 generate.bat,程序自動將配置文件 resources/mbgconfig.xml 中配置的表格映射成相對應的文件。
將上面生成后的 com.chanshuyi.model.User 類拷貝至 model 模塊的 com.chanshuyi.model 包。
三、配置 interface 模塊
打開 interface 模塊的 pom.xml 模塊,加入對於 SuperDemo 下 model 模塊的依賴:
<dependency> <groupId>com.chanshuyi.SuperDemo</groupId> <artifactId>model</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
創建 com.chanshuyi.dao.IUserDao 接口
package com.chanshuyi.dao; import com.chanshuyi.model.User; import java.util.List; import java.util.Map; /** * Created by chanshuyi on 2015/12/26. */ public interface IUserDao { User getUserById(int userId); /** * * @param param Map中的key要與數據庫表中的字段名相同 * @return */ User getUserByMapSql(Map<String, String> param); List<User> getUserListByMapSql(Map<String, String> param); }
創建 com.chanshuyi.service.IUserService 接口
package com.chanshuyi.service; import com.chanshuyi.model.User; import java.util.List; import java.util.Map; /** * Created by chanshuyi on 2015/12/26. */ public interface IUserService { User getUserById(int userId); /** * * @param param Map中的key要與數據庫表中的字段名相同 * @return */ User getUserByMapSql(Map<String, String> param); List<User> getUserListByMapSql(Map<String, String> param); }
四、配置 provider 模塊
打開 provider 模塊的 pom.xml 文件,加入全局屬性聲明
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <springframework.version>4.1.6.RELEASE</springframework.version> <commonsLogging.version>1.2</commonsLogging.version> </properties>
導入 Spring、MyBatis 等依賴
<dependencies> <!-- ********************** MyBatis ********************** --> <!-- MyBatis 核心包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.1.1</version> </dependency> <!-- 添加mybatis與Spring整合的核心包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.1.1</version> </dependency> <!-- ********************** Spring ********************** --> <!-- 添加Spring-core包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-tx包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework.version}</version> </dependency> <!-- Spring ORM 相關--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-jdbc包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${springframework.version}</version> </dependency> <!--添加spring-web包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-context包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commonsLogging.version}</version> </dependency> <!--添加aspectjweaver包 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.5</version> </dependency> <!-- ********************** JDBC ********************** --> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency> <!-- Druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.6</version> </dependency> <!-- ********************** DUBBO ********************** --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <!-- ********************** Zookeeper ********************** --> <!-- zookeeper --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.3.3</version> <exclusions> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> </exclusions> </dependency> <!-- ********************** 其他 ********************** --> <!-- 核心接口 --> <dependency> <groupId>com.chanshuyi.SuperDemo</groupId> <artifactId>interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
在 resources 目錄下創建 applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> <!-- ================================== import sub-config file ================================== --> <import resource="spring-mybatis.xml" /> <!-- ================================== /import sub-config file ================================== --> </beans>
創建 MyBatis 配置文件 spring-mybatis.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 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"> 6 7 <!-- 引入外部properties文件 --> 8 <context:property-placeholder location="classpath:jdbc.properties" /> 9 10 <!-- ====================================================== Add MyBatis Support Start ====================================================== --> 11 <!-- 配置寫數據源 --> 12 <bean id="dataSourceWrite" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 13 <!-- 基本屬性 url、user、password --> 14 <property name="url" value="${jdbc.master.url}" /> 15 <property name="username" value="${jdbc.master.username}" /> 16 <property name="password" value="${jdbc.master.password}" /> 17 <!-- 配置初始化大小、最小、最大 --> 18 <property name="initialSize" value="${jdbc.master.initialSize}" /> 19 <property name="minIdle" value="${jdbc.master.minIdle}" /> 20 <property name="maxActive" value="${jdbc.master.maxActive}" /> 21 <!-- 配置獲取連接等待超時的時間 --> 22 <property name="maxWait" value="60000" /> 23 <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 --> 24 <property name="timeBetweenEvictionRunsMillis" value="60000" /> 25 <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 --> 26 <property name="minEvictableIdleTimeMillis" value="300000" /> 27 <property name="validationQuery" value="SELECT '1'" /> 28 <property name="testWhileIdle" value="true" /> 29 <property name="testOnBorrow" value="true" /> 30 <property name="testOnReturn" value="false" /> 31 <!-- 打開PSCache,並且指定每個連接上PSCache的大小 mysql false --> 32 <property name="poolPreparedStatements" value="false" /> 33 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> 34 <!-- 配置監控統計攔截的filters --> 35 <property name="filters" value="config,stat,log4j,wall" /> 36 <property name="connectionProperties" value="config.decrypt=false" /> 37 </bean> 38 <!-- 配置讀數據源 --> 39 <bean id="dataSourceRead" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 40 <!-- 基本屬性 url、user、password --> 41 <property name="url" value="${jdbc.slave.url}" /> 42 <property name="username" value="${jdbc.slave.username}" /> 43 <property name="password" value="${jdbc.slave.password}" /> 44 <!-- 配置初始化大小、最小、最大 --> 45 <property name="initialSize" value="${jdbc.slave.initialSize}" /> 46 <property name="minIdle" value="${jdbc.slave.minIdle}" /> 47 <property name="maxActive" value="${jdbc.slave.maxActive}" /> 48 <!-- 配置獲取連接等待超時的時間 --> 49 <property name="maxWait" value="60000" /> 50 <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閑連接,單位是毫秒 --> 51 <property name="timeBetweenEvictionRunsMillis" value="60000" /> 52 <!-- 配置一個連接在池中最小生存的時間,單位是毫秒 --> 53 <property name="minEvictableIdleTimeMillis" value="300000" /> 54 <property name="validationQuery" value="SELECT '1'" /> 55 <property name="testWhileIdle" value="true" /> 56 <property name="testOnBorrow" value="false" /> 57 <property name="testOnReturn" value="false" /> 58 <!-- 打開PSCache,並且指定每個連接上PSCache的大小 mysql false --> 59 <property name="poolPreparedStatements" value="false" /> 60 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> 61 <!-- 配置監控統計攔截的filters --> 62 <property name="filters" value="config,stat,log4j,wall" /> 63 <property name="connectionProperties" value="config.decrypt=false" /> 64 </bean> 65 66 <!-- 可寫的SessionFactory --> 67 <bean id="sqlWriteSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="singleton"> 68 <property name="dataSource" ref="dataSourceWrite" /> 69 <property name="configLocation" value="classpath:mybatis-config.xml" /> 70 </bean> 71 <!-- 只讀的SessionFactory --> 72 <bean id="sqlReadOnlySessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="singleton"> 73 <property name="dataSource" ref="dataSourceRead" /> 74 <property name="configLocation" value="classpath:mybatis-config.xml" /> 75 </bean> 76 77 <!-- 可寫的Session --> 78 <bean id="writableSQLSession" class="org.mybatis.spring.SqlSessionTemplate"> 79 <constructor-arg index="0" ref="sqlWriteSessionFactory" /> 80 </bean> 81 <!-- 只讀的Session --> 82 <bean id="readonlySQLSession" class="org.mybatis.spring.SqlSessionTemplate"> 83 <constructor-arg index="0" ref="sqlReadOnlySessionFactory" /> 84 </bean> 85 <!-- ====================================================== Add MyBatis Support End ====================================================== --> 86 </beans>
配置 MyBatis 注解掃描路徑,創建 mybatis-config.xml 配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <mappers> <!-- 配置掃描的Mapper類 --> <package name="com.chanshuyi.dao.mapper"/> </mappers> </configuration>
創建數據庫配置文件 jdbc.properties
############################ MySQL/Oracle/SQLServer Database Configuratioin Info ###############################
# MySQL Master DB Info
jdbc.master.dialet=org.hibernate.dialect.MySQLDialect
jdbc.master.driverClassName=com.mysql.jdbc.Driver
jdbc.master.url=jdbc:mysql://127.0.0.1:3306/superdemo
jdbc.master.username=root
jdbc.master.password=sa
# MySQL Slave DB Info
jdbc.slave.dialet=org.hibernate.dialect.MySQLDialect
jdbc.slave.driverClassName=com.mysql.jdbc.Driver
jdbc.slave.url=jdbc:mysql://localhost:3306/superdemo
jdbc.slave.username=root
jdbc.slave.password=sa
############################## Connection Pool Configuration Info ##############################################
# MySQL Master DB Setting
jdbc.master.initialSize = 10
jdbc.master.minIdle = 0
jdbc.master.maxActive = 30
# MySQL Slave DB Setting
jdbc.slave.initialSize = 10
jdbc.slave.minIdle = 0
jdbc.slave.maxActive = 30
創建 resources/log4j.properties 文件,提供日志記錄。
#Console Log
log4j.rootLogger=info, console, file
# Write to Console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=INFO
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%5p %d{MM-dd HH:mm:ss}(%F:%L): %m%n
# Write to File
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=${catalina.home}app/log/log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%5p %d{MM-dd HH:mm:ss}(%F:%L): %m%n
在 com.chanshuyi.dao.mapper.UserMapper 類中增加 getUserListByMapSql 接口:
/** * 根據參數構造SQL進行查詢 * @param param * @return */ @SelectProvider(type = UserSqlProvider.class, method = "getUserListByMapSql") List<User> getUserListByMapSql(@Param("param") Map<String, String> param);
在 UserSqlProvider 類增加對上面接口 SQL 的實現:
/** * 獲取查詢SQL * @param param * @return */ public String getUserListByMapSql(Map<String, Object> param) { StringBuilder builder = new StringBuilder(); Map<String, String> realParam = (Map<String, String>)param.get("param"); //add select part builder.append(" select * from user where 1 = 1 "); //add condition part String conditionStr = ""; if(!StringUtil.isNullOrEmpty(realParam)){ conditionStr = getQueryCondition(realParam); if(!StringUtil.isNullOrEmpty(conditionStr)){ builder.append(conditionStr); } } return new String(builder); } public String getQueryCondition(Map<String, String> param){ StringBuilder builder = new StringBuilder(); //if param is null or empty, return empty String if(param == null || param.size() < 1){ return ""; } for(String key : param.keySet()){ String value = param.get(key); if(value != null && !value.isEmpty()){ builder.append(" and " + key + " = '" + value + "'"); } } return new String(builder); }
上面用到了 StringUtil.java,我們在 com.chanshuyi.util 中導入它:

package com.mszz.util; import java.util.Collection; import java.util.Map; /** * 字符串工具類 * @author chenxinquan * */ public class StringUtil { /** * 判斷對象或對象數組中每一個對象是否為空: 對象為null,字符序列長度為0,集合類、Map為empty * @author zl * @param obj * @return */ public static boolean isNullOrEmpty(Object obj) { if (obj == null) return true; if (obj instanceof CharSequence) return ((CharSequence) obj).length() == 0; if (obj instanceof Collection) return ((Collection) obj).isEmpty(); if (obj instanceof Map) return ((Map) obj).isEmpty(); if (obj instanceof Object[]) { Object[] object = (Object[]) obj; if (object.length == 0) { return true; } boolean empty = true; for (int i = 0; i < object.length; i++) { if (!isNullOrEmpty(object[i])) { empty = false; break; } } return empty; } return false; } } StringUtil.java
創建 com.chanshuyi.dao.impl.BaseDao.java 類,提供基本的數據庫讀寫對象,並用注解方式將 SqlSession 注入。
package com.chanshuyi.dao.impl;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
/**
* 所有Service的基類,用來注入sqlSession
*/
public class BaseDao {
/**
* 可寫的sqlSession
*/
@Autowired
protected SqlSession writableSQLSession;
/**
* 只讀的sqlSession
*/
@Autowired
protected SqlSession readonlySQLSession;
}
創建 com.chanshuyi.dao.impl.UserDaoImpl.java 繼承 BaseDao.java、實現 IUserDao 接口,並用 @Repository 創建名稱為 userDao 的對象。
package com.chanshuyi.dao.impl; import com.chanshuyi.dao.IUserDao; import com.chanshuyi.dao.mapper.UserMapper; import com.chanshuyi.model.User; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Map; /** * Created by Administrator on 2015/12/26. */ @Repository("userDao") public class UserDaoImpl extends BaseDao implements IUserDao { private static Log logger = LogFactory.getLog(UserDaoImpl.class); @Override public User getUserById(int userId) { UserMapper mapper = readonlySQLSession.getMapper(UserMapper.class); return mapper.selectByPrimaryKey(userId); } /** * * @param param * @return */ @Override public User getUserByMapSql(Map<String, String> param) { logger.info("getUserByMapSql 根據動態參數查詢用戶對象"); return getUserListByMapSql(param).size() > 0 ? getUserListByMapSql(param).get(0) : null; } /** * get**MapSql()類的方法只能用於各參數的等於查詢 * 例如:select * from user where username = 1 and password = 3 (正確) * select * from user where username in (1,2,3) (錯誤,無法實現) * @param param * @return */ @Override public List<User> getUserListByMapSql(Map<String, String> param) { logger.info("getUserListByMapSql 根據動態參數查詢用戶對象列表"); UserMapper mapper = readonlySQLSession.getMapper(UserMapper.class); return mapper.getUserListByMapSql(param); } }
創建 com.chanshuyi.service.impl.UserServiceImpl 類,並添加 @Service 注解創建名稱為 userService 的對象,並將 userDao 對象注入。
package com.chanshuyi.service.impl; import com.chanshuyi.dao.IUserDao; import com.chanshuyi.model.User; import com.chanshuyi.service.IUserService; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; /** * Created by Administrator on 2015/6/18. */ @Service("userService") public class UserServiceImpl implements IUserService { private static Log logger = LogFactory.getLog(UserServiceImpl.class); @Autowired IUserDao userDao; @Override public User getUserById(int userId) { return userDao.getUserById(userId); } @Override public User getUserByMapSql(Map<String, String> param) { return userDao.getUserByMapSql(param); } @Override public List<User> getUserListByMapSql(Map<String, String> param) { return userDao.getUserListByMapSql(param); } }
DAO 和 SERVICE 層的配置寫好之后,需要在 applicationContext.xml 文件中配置掃描路徑:
<!-- 開啟注解相關處理器 --> <context:annotation-config/> <!-- 自動掃描Spring注解(如:autowired) --> <context:component-scan base-package="com.chanshuyi.dao.impl, com.chanshuyi.service.impl"/>
到這里基本 provider 大部分配置已經結束,下面我們需要啟動 provider 模塊,讓它對外提供服務。
創建 com.chanshuyi.util.SystemDetails 類,用來打印系統的基本信息:
package com.chanshuyi.util; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; public class SystemDetails { /** * 輸出系統基本信息 */ public static void outputDetails() { timeZone(); currentTime(); os(); } /** * 輸出系統時區 */ private static void timeZone() { Calendar cal = Calendar.getInstance(); TimeZone timeZone = cal.getTimeZone(); System.out.println("系統時區:" + timeZone.getDisplayName()); } /** * 輸出系統時間 */ private static void currentTime() { String fromFormat = "yyyy-MM-dd HH:mm:ss"; SimpleDateFormat format = new SimpleDateFormat(fromFormat); Date myDate = new Date(); System.out.println("系統時間:" + format.format(myDate)); } /** * 輸出系統基本配置 */ private static void os() { String osName = System.getProperty("os.name"); //操作系統名稱 System.out.println("當前系統:" + osName); String osArch = System.getProperty("os.arch"); //操作系統構架 System.out.println("當前系統架構" + osArch); String osVersion = System.getProperty("os.version"); //操作系統版本 System.out.println("當前系統版本:" + osVersion); } }
創建 com.chanshuyi.util.BeanFactoryUtil,用於加載 Spring 配置文件:
package com.chanshuyi.util; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanFactoryUtil { private static ApplicationContext ctx_producer = null; public final static String ApplicationContextRoot = ""; public final static String ApplicationContextPath = ApplicationContextRoot + "applicationContext.xml"; public static void init() { if (ctx_producer == null) { synchronized (BeanFactoryUtil.class) { if(ctx_producer == null){ String[] configLocations = new String[]{ApplicationContextPath}; ctx_producer = new ClassPathXmlApplicationContext(configLocations); } } } } public static ApplicationContext getContext() { if (ctx_producer == null) { init(); } return ctx_producer; } }
創建 com.chanshuyi.Launcher 類,用於啟動 provider 服務,加載 Spring 配置文件,對外提供服務:
package com.chanshuyi; import com.chanshuyi.util.BeanFactoryUtil; import com.chanshuyi.util.SystemDetails; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Launcher { private static Log logger = LogFactory.getLog(Launcher.class); /** * @param args */ public static void main(String[] args) { System.out.println("======================="); System.out.println(" Core包啟動 "); SystemDetails.outputDetails(); System.out.println("======================="); getLocalip(); // 初始化spring logger.info("開始初始化core服務"); BeanFactoryUtil.init(); try{ System.in.read(); } catch (Exception e) { e.printStackTrace(); } } /** * 取得本機ip地址 注意:Spring RmiServiceExporter取得本機ip的方法:InetAddress.getLocalHost() */ private static void getLocalip() { try { System.out.println("服務暴露的ip: " + java.net.InetAddress.getLocalHost().getHostAddress()); } catch (Exception e) { System.out.println(e.getMessage()); } } }
我們還要創建一個 spring-provider.xml 文件,告訴 dubbo 我們的基本信息以及對外提供的服務:
<?xml version="1.0" encoding="UTF-8"?> <!-- 添加 DUBBO SCHEMA --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 應用名 --> <!-- 需要用到多個注冊中心,因此在 dubbo.properties 中聲明 --> <dubbo:application name="superdemo_provider"/> <!-- 連接到哪個本地注冊中心 --> <dubbo:registry id="superdemo_zk" address="zookeeper://localhost:2181"/> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="28080"/> <!-- 聲明需要暴露的服務接口 --> <dubbo:service registry="superdemo_zk" timeout="3000" interface="com.chanshuyi.service.IUserService" ref="userService"/> </beans>
記得在 applicationContext.xml 文件中將 spring-provider.xml 文件導入進去:
<import resource="spring-provider.xml" />
五、配置 consumer 模塊
打開 pom.xml 文件,導入全局配置變量以及所需的 SpringMVC、Dubbo、Zookeeper、com.chanshuyi.SuperDemo.interface 依賴:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <springframework.version>4.1.6.RELEASE</springframework.version> <commonsLogging.version>1.2</commonsLogging.version> </properties> <dependencies> <!-- ********************** Spring ********************** --> <!-- Spring MVC 依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加Spring-core包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-tx包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework.version}</version> </dependency> <!-- Spring ORM 相關--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-jdbc包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${springframework.version}</version> </dependency> <!--添加spring-web包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-context包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commonsLogging.version}</version> </dependency> <!--添加aspectjweaver包 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.5</version> </dependency> <!-- ********************** DUBBO ********************** --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.3.3</version> <exclusions> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> </exclusions> </dependency> <!-- ********************** Zookeeper ********************** --> <!-- zookeeper --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- ********************** interface 接口 ********************** --> <dependency> <groupId>com.chanshuyi.SuperDemo</groupId> <artifactId>interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
之后導入 Tomcat 啟動插件,我們將通過 Maven 方式啟動 Tomcat,這樣就不必在本地配置一個 Tomcat 服務器。
<!-- Maven的Tomcat插件(支持Maven以"tomcat7:run"方式啟動web項目) --> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>5050</port> <path>/</path> <uriEncoding>UTF-8</uriEncoding> <finalName>mgr</finalName> <server>tomcat7</server> </configuration> </plugin>
配置完成后的 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/maven-v4_0_0.xsd"> <parent> <artifactId>SuperDemo</artifactId> <groupId>com.chanshuyi.SuperDemo</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.chanshuyi.SuperDemo</groupId> <artifactId>app</artifactId> <packaging>war</packaging> <name>app Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <springframework.version>4.1.6.RELEASE</springframework.version> <commonsLogging.version>1.2</commonsLogging.version> </properties> <dependencies> <!-- ********************** Spring ********************** --> <!-- Spring MVC 依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加Spring-core包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-tx包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework.version}</version> </dependency> <!-- Spring ORM 相關--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-jdbc包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${springframework.version}</version> </dependency> <!--添加spring-web包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <!-- 添加spring-context包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commonsLogging.version}</version> </dependency> <!--添加aspectjweaver包 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.5</version> </dependency> <!-- ********************** DUBBO ********************** --> <dependency> <groupId>com.alibaba</groupId> <artifactId>dubbo</artifactId> <version>2.5.3</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.3.3</version> <exclusions> <exclusion> <groupId>com.sun.jmx</groupId> <artifactId>jmxri</artifactId> </exclusion> <exclusion> <groupId>com.sun.jdmk</groupId> <artifactId>jmxtools</artifactId> </exclusion> <exclusion> <groupId>javax.jms</groupId> <artifactId>jms</artifactId> </exclusion> </exclusions> </dependency> <!-- ********************** Zookeeper ********************** --> <!-- zookeeper --> <dependency> <groupId>com.github.sgroschupf</groupId> <artifactId>zkclient</artifactId> <version>0.1</version> </dependency> <!-- ********************** interface 接口 ********************** --> <dependency> <groupId>com.chanshuyi.SuperDemo</groupId> <artifactId>interface</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <finalName>consumer</finalName> <!-- Maven的Tomcat插件(支持Maven以"tomcat7:run"方式啟動web項目) --> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.1</version> <configuration> <port>5050</port> <path>/</path> <uriEncoding>UTF-8</uriEncoding> <finalName>mgr</finalName> <server>tomcat7</server> </configuration> </plugin> </plugins> </build> </project>
之后在 main 目錄下創建 java 目錄,並設置為 Java Source(源碼目錄):
之后創建 com.chanshuyi.controller.UserController 類:
package com.chanshuyi.controller; import com.chanshuyi.service.IUserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.Map; /** * Created by Administrator on 2015/6/18. */ @Controller("userAction") @RequestMapping(value="/login") public class UserController{ private static Logger logger = LoggerFactory.getLogger(UserController.class); private String message; private String username; private String password; @Autowired private IUserService userService; @Autowired private HttpServletRequest request; @RequestMapping("") public String login(@RequestParam(value = "username", required = false) String username, @RequestParam(value = "password", required = false) String password){ try{ Map<String, String> param = new HashMap<String, String>(); param.put("username", username); param.put("password", password); if(userService.getUserByMapSql(param) != null){ message = "登錄成功!"; logger.info(message); }else{ message = "登錄失敗!"; logger.info(message); } }catch(Exception e){ logger.warn(e.getMessage()); e.printStackTrace(); } request.setAttribute("message", message); return "index"; // 轉到webapp/index.jsp頁面 } /******** set/get ********/ public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
創建 dubbo 配置文件 spring-consumer.xml,這個文件告訴 dubbo 本模塊的基本信息以及請求的服務:
<?xml version="1.0" encoding="UTF-8"?> <!-- 添加 DUBBO SCHEMA --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- 應用名 --> <!-- 需要用到多個注冊中心,因此在 dubbo.properties 中聲明 --> <dubbo:application name="superdemo_consumer"/> <!-- 連接到哪個本地注冊中心 --> <dubbo:registry id="superdemo_zk" address="zookeeper://localhost:2181"/> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="28080"/> <!-- 聲明需要引用的服務接口 --> <dubbo:reference registry="superdemo_zk" id="userService" interface="com.chanshuyi.service.IUserService" check="false"/> </beans>
別忘了在 applicationContext.xml 中將 spring-consumer.xml 加入進去
<import resource="spring-consumer.xml" />
創建 webapp/index.jsp 文件
<%@page language="java" pageEncoding="UTF-8"%> <%@ page contentType="text/html;charset=utf-8" %> <%@ page isELIgnored="false"%> <html> <head> <meta charset="utf-8"> </head> <body> <h2>Hello World!</h2> <%-- 通過Struts傳遞參數,數據傳遞方式必須選擇post,否則編碼錯誤! --%> <form action="login" method="post" > <p id="message">${message}</p> <b>Username:</b><input type="text" id="name" name="username" /><br> <b>Password:</b><input type="password" id="password" name="password"/><br> <input type="submit" value="Login"/> </form> </body> </html>
修改 web.xml 文件,加載 SpringMVC 處理器
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 字符集過濾器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- spring MVC的核心就是DispatcherServlet,使用springMVC的第一步就是將下面的servlet放入web.xml servlet-name屬性非常重要,默認情況下,DispatchServlet會加載這個名字-servlet.xml的文件,如下,就會加載 dispather-servlet.xml,也是在WEN-INF目錄下。--> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 設置dispatchservlet的匹配模式,通過把dispatchservlet映射到/,默認servlet會處理所有的請求,包括靜態資源 --> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
創建 SprngMVC 配置文件 spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd" default-lazy-init="true"> <!-- 通過mvc:resources設置靜態資源,這樣servlet就會處理這些靜態資源,而不通過控制器 --> <!-- 設置不過濾內容,比如:css,jquery,img 等資源文件 --> <!--<mvc:resources location="/*.html" mapping="/**.html" />--> <!--<mvc:resources location="/css/*" mapping="/css/**" />--> <!--<mvc:resources location="/js/*" mapping="/js/**" />--> <!--<mvc:resources location="/images/*" mapping="/images/**" />--> <!-- 添加注解驅動 --> <mvc:annotation-driven /> <!-- 默認掃描的包路徑 --> <context:component-scan base-package="com.chanshuyi.controller" /> <!-- mvc:view-controller可以在不需要Controller處理request的情況,轉向到設置的View --> <!-- 像下面這樣設置,如果請求為/,則不通過controller,而直接解析為/index.jsp --> <!--<mvc:view-controller path="/" view-name="index" />--> <!-- 配置 SpringMVC Controller 轉發JSP頁面的路徑 --> <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property> <!-- 配置jsp路徑前綴 --> <property name="prefix" value="/"></property> <!-- 配置URl后綴 --> <property name="suffix" value=".jsp"></property> </bean> </beans>
配置好之后將整個項目編譯一次,為整個項目配置 Maven 命令:
六、啟動 provider 模塊和 consumer 模塊測試
啟動 provider 模塊
先啟動 zookeeper,再打開 Launcher.java 運行 main() 方法就可以了。看看控制台和 zookeeper 輸出,如果沒有報錯,那就是啟動成功了。
啟動 consumer 模塊
為 consumer 模塊配置 Maven 啟動命令:"tomcat7:run"
點擊啟動項目
測試聯通
打開瀏覽器輸入:http://localhost:5050/index.jsp
輸入 admin/password,點擊 Login 按鈕
提示登錄成功,說明項目已經成功部署好。
鏈接:http://pan.baidu.com/s/1pKamdib 密碼:vutw