一、整合
spring3版本: 3.1.1
struts2版本: 2.3.4
jpa2.0實現: hibernate 4.1.1
連接池: BoneCP 0.7.1 (要求JDK6以上,應用服務器也需要保證JDK6以上)
緩存: ehcache 2.5.2
1、在MyEclipse下建立一個Web Project,把相應的jar到放到WEB-INF\lib目錄中
所需的jar:
antlr-2.7.7.jar
aopalliance-1.0.jar
aspectjrt.jar
aspectjweaver.jar
bonecp-0.7.1.RELEASE.jar
bonecp-provider-0.7.1-rc2.jar
bonecp-spring-0.7.1-rc1.jar
cglib-nodep-2.2.jar
commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar
commons-lang3-3.1.jar
commons-logging-1.1.1.jar
dom4j-1.6.1.jar
ehcache-core-2.5.2.jar
ehcache-spring-annotations-1.2.0.jar
freemarker-2.3.19.jar
guava-12.0.jar
hibernate-commons-annotations-4.0.1.Final.jar
hibernate-core-4.1.1.Final.jar
hibernate-entitymanager-4.1.1.Final.jar
hibernate-jpa-2.0-api-1.0.1.Final.jar
javassist-3.15.0-GA.jar
jboss-logging-3.1.0.GA.jar
jboss-transaction-api_1.1_spec-1.0.0.Final.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.6-bin.jar
ognl-3.0.5.jar
org.springframework.aop-3.1.1.RELEASE.jar
org.springframework.asm-3.1.1.RELEASE.jar
org.springframework.aspects-3.1.1.RELEASE.jar
org.springframework.beans-3.1.1.RELEASE.jar
org.springframework.context-3.1.1.RELEASE.jar
org.springframework.context.support-3.1.1.RELEASE.jar
org.springframework.core-3.1.1.RELEASE.jar
org.springframework.expression-3.1.1.RELEASE.jar
org.springframework.jdbc-3.1.1.RELEASE.jar
org.springframework.jms-3.1.1.RELEASE.jar
org.springframework.orm-3.1.1.RELEASE.jar
org.springframework.oxm-3.1.1.RELEASE.jar
org.springframework.test-3.1.1.RELEASE.jar
org.springframework.transaction-3.1.1.RELEASE.jar
org.springframework.web-3.1.1.RELEASE.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.6.1.jar
struts2-core-2.3.4.jar
struts2-spring-plugin-2.3.4.jar
xwork-core-2.3.4.jar
2、JPA2.0的配置
在src目錄下建立一個名為META-INF的文件夾,在META-INF下建立一個名為persistence.xml的文件。
在persistence.xml文件中,JPA和BoneCP連接池進行了整合。
persistence.xml文件內容:
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <!-- 在使用容器管理的多數據源的情況下使用jta,不能使用RESOURCE-LOCAL選項 --> <persistence-unit name="APP_JPA" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="javax.persistence.validation.mode" value="none"/> <!-- 如果是hibernte3,使用 <property name="hibernate.connection.provider_class" value="com.jolbox.bonecp.provider.BoneCPConnectionProvider"/> --> <!--hibernte4使用 --> <property name="hibernate.service.jdbc.connections.spi.provider_class" value="com.jolbox.bonecp.provider.BoneCPConnectionProvider"/> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="root"/> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/spring_struts_jpa?useUnicode=true&characterEncoding=UTF-8"/> <property name="hibernate.max_fetch_depth" value="3"/> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.jdbc.fetch_size" value="18"/> <property name="hibernate.jdbc.batch_size" value="10"/> <property name="hibernate.show_sql" value="true"/> <property name="hibernate.format_sql" value="true"/> <!-- BoneCP參數設置 --> <!-- 設置分區個數.這個參數默認為1,建議3-4(根據特定應用程序而定) --> <property name="bonecp.partitionCount" value="3"/> <!-- 設置每個分區含有connection最大個數.這個參數默認為2.如果小於2,BoneCP將設置為50. 比如:partitionCount設置為3,maxConnectionPerPartition設置為5,你就會擁有總共15個connection.--> <property name="bonecp.maxConnectionsPerPartition" value="20"/> <!-- 設置每個分區含有連接最大小個數.這個參數默認為0 --> <property name="bonecp.minConnectionsPerPartition" value="10"/> <!-- 設置分區中的連接增長數量.這個參數默認為1 --> <property name="bonecp.acquireIncrement" value="5"/> <!-- 設置連接池閥值.這個參數默認為20.如果小於0或是大於100,BoneCP將設置為20. 連接池為每個分區至少維持20%數量的可用connection --> <property name="bonecp.poolAvailabilityThreshold" value="20"/> <!-- 設置connection助手線程個數.這個參數默認為3.如果小於0,BoneCP將設置為3. --> <property name="bonecp.releaseHelperThreads" value="3"/> <!-- 設置connection的空閑存活時間.這個參數默認為60,單位:分鍾.設置為0該功能失效. 通過ConnectionTesterThread觀察每個分區中的connection,如果這個connection距離最 后使用的時間大於這個參數就會被清除 --> <property name="bonecp.idleMaxAge" value="240"/> <!-- 設置測試connection的間隔時間.這個參數默認為240,單位:分鍾.設置為0該功能失效. 通過ConnectionTesterThread觀察每個分區中的connection, 如果這個connection距離最后 使用的時間大於這個參數並且距離上一次測試的時間大於這個參數就會向數據庫發送一條測試語句, 如果執行失敗則將這個connection清除. --> <property name="bonecp.idleConnectionTestPeriod" value="60"/> <!-- 設置statement助手線程個數.這個參數默認為3.如果小於0,BoneCP將設置為3. --> <property name="bonecp.statementsCacheSize" value="20"/> </properties> </persistence-unit> </persistence>
3、Struts2的配置
在src目錄下建立一個struts.xml文件。
struts.xml文件內容:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <constant name="struts.objectFactory" value="spring" /> <constant name="struts.ui.theme" value="simple" /> <constant name="struts.action.extension" value="action" /> <package name="default" namespace="/" extends="struts-default"> </package> <!-- Add packages here --> </struts>
4、ehcache緩存配置
在src目錄下建立名為ehcache.xml的文件。
ehcache.xml文件內容:
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- <diskStore path="java.io.tmpdir"/> --> <!-- 配置緩存文件存放路徑 --> <diskStore path="E:/cachetmpdir" /> <!-- 1.必須要有的屬性: name: cache的名字,用來識別不同的cache,必須惟一。 maxElementsInMemory: 內存管理的緩存元素數量最大限值。 maxElementsOnDisk: 硬盤管理的緩存元素數量最大限值。默認值為0,就是沒有限制。 eternal: 設定元素是否持久話。若設為true,則緩存元素不會過期。 overflowToDisk: 設定是否在內存填滿的時候把數據轉到磁盤上。 2.下面是一些可選屬性: timeToIdleSeconds: 設定元素在過期前空閑狀態的時間,只對非持久性緩存對象有效。默認值為0,值為0意味着元素可以閑置至無限長時間。 timeToLiveSeconds: 設定元素從創建到過期的時間。其他與timeToIdleSeconds類似。 diskPersistent: 設定在虛擬機重啟時是否進行磁盤存儲,默認為false.(我的直覺,對於安全小型應用,宜設為true)。 diskExpiryThreadIntervalSeconds: 訪問磁盤線程活動時間。 diskSpoolBufferSizeMB: 存入磁盤時的緩沖區大小,默認30MB,每個緩存都有自己的緩沖區。 memoryStoreEvictionPolicy: 元素逐出緩存規則。共有三種,Recently Used (LRU)最近最少使用,為默認。 First In First Out (FIFO),先進先出。Less Frequently Used(specified as LFU)最少使用 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
<cache name="userCache"
memoryStoreEvictionPolicy="LRU"
eternal="false"
maxElementsInMemory="20"
overflowToDisk="false"
diskPersistent="false" />
</ehcache>
5、Spring的配置
spring管理JPA的事務、struts2的action。
在WEB-INF目錄下建立一個名為applicationContext.xml的文件。
applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd"> <!-- 定義組件掃描,配置需要掃描的包--> <context:component-scan base-package="cn.luxh.app" /> <!-- 定義實體管理器工廠 --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="APP_JPA"/> </bean> <!-- 配置事務管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!-- 啟用 annotation事務--> <tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 啟用緩存注解功能 --> <ehcache:annotation-driven cache-manager="ehCacheManager" /> <!-- cacheManager工廠類,指定ehcache.xml的位置 --> <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:/ehcache.xml"/>
</beans>
6、web.xml配置
web.xml文件內容:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>app</display-name> <!-- 配置Log4j --> <context-param> <param-name>webAppRootKey</param-name> <param-value>spring_struts_jpa.root</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <!-- 配置編碼過濾器 --> <filter> <filter-name>characterEncodingFilter</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> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 加載Spring監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <!--配置緩存清除監聽器 處理由 JavaBean Introspector功能而引起的緩存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!--配置Struts2過濾器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
7、ok,Spring3+Struts2+JPA2.0整合完畢。
二、使用
1、實體類。
@Entity @Table(name="t_user") public class User implements Serializable{ private static final long serialVersionUID = -3647733101497063659L; @Id @GeneratedValue private Long id; /**賬號*/ @Column(length=32) private String account; /**密碼*/ @Column(length=32) private String password; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
2、DAO
1)寫一個BaseDao接口和BaseDaoImpl實現類,這里是示例,只寫兩個方法。
@Repository用於將數據訪問層 (DAO 層 ) 的類標識為 Spring Bean。
BaseDao.java:
public interface BaseDao { /** * 新增實體 * @param entity 要新增的實體 */ public void save(Object entity); /** * 根據主鍵查詢 * @param <T> * @param clazz 實體類的Class * @param id 主鍵 * @return */ public <T> T getById(Class<T> clazz,Object id); }
BaseDaoImpl.java:
@Repository(value="baseDao") public class BaseDaoImpl implements BaseDao { @PersistenceContext protected EntityManager em; public void save(Object entity) { em.persist(entity); } public <T> T getById(Class<T> clazz, Object id) { return em.find(clazz, id); } }
2)寫一個用戶數據訪問的UserDao接口和UserDaoImpl實現類。
UserDao.java:
public interface UserDao extends BaseDao{ }
UserDaoImpl.java:
@Repository(value="userDao") public class UserDaoImpl extends BaseDaoImpl implements UserDao { }
3、Service
1)BaseService接口。
public interface BaseService { /** * 新增實體 * @param entity */ public void save(Object entity); /** * 根據主鍵查詢 * @param <T> * @param clazz 實體類的Class * @param id 主鍵 * @return */ public <T> T getById(Class<T> clazz,Object id); }
2)用戶管理服務接口和實現類。
UserService.java:
public interface UserService extends BaseService { }
UserServiceImpl.java:
@Service(value="userService") public class UserServiceImpl implements UserService { @Resource(name="userDao") private UserDao userDao; @Override @Transactional(propagation=Propagation.REQUIRED) @TriggersRemove(cacheName="userCache",removeAll=true) public void save(Object entity) { userDao.save(entity); } @Override @Transactional(propagation=Propagation.REQUIRED,readOnly=true) @Cacheable(cacheName="userCache") public <User> User getById(Class<User> clazz, Object id) { return userDao.getById(clazz, id); } }
@Service(value="userService") 用於將業務層的類標識為 Spring Bean。
@Resource(name="userDao") 根據名字注入資源
@Transactional(propagation=Propagation.REQUIRED) 注解式事務
@Cacheable(cacheName="userCache") 注解式緩存,將方法的返回值加入到名稱為userCache的緩存中
@TriggersRemove(cacheName="userCache",removeAll=true) 注解式緩存,清除緩存名稱為userCache緩存
4、緩存文件配置
在ehcache.xml中配置userCache緩存。
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- <diskStore path="java.io.tmpdir"/> --> <!-- 配置緩存文件存放路徑 --> <diskStore path="E:/cachetmpdir" /> <!-- 1.必須要有的屬性: name: cache的名字,用來識別不同的cache,必須惟一。 maxElementsInMemory: 內存管理的緩存元素數量最大限值。 maxElementsOnDisk: 硬盤管理的緩存元素數量最大限值。默認值為0,就是沒有限制。 eternal: 設定元素是否持久話。若設為true,則緩存元素不會過期。 overflowToDisk: 設定是否在內存填滿的時候把數據轉到磁盤上。 2.下面是一些可選屬性: timeToIdleSeconds: 設定元素在過期前空閑狀態的時間,只對非持久性緩存對象有效。默認值為0,值為0意味着元素可以閑置至無限長時間。 timeToLiveSeconds: 設定元素從創建到過期的時間。其他與timeToIdleSeconds類似。 diskPersistent: 設定在虛擬機重啟時是否進行磁盤存儲,默認為false.(我的直覺,對於安全小型應用,宜設為true)。 diskExpiryThreadIntervalSeconds: 訪問磁盤線程活動時間。 diskSpoolBufferSizeMB: 存入磁盤時的緩沖區大小,默認30MB,每個緩存都有自己的緩沖區。 memoryStoreEvictionPolicy: 元素逐出緩存規則。共有三種,Recently Used (LRU)最近最少使用,為默認。 First In First Out (FIFO),先進先出。Less Frequently Used(specified as LFU)最少使用 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <!-- User cache --> <cache name="userCache" maxElementsInMemory="10000" maxElementsOnDisk="1000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" /> </ehcache>
5、Action
UserAction.java:
@Controller @Scope("prototype") public class UserAction extends ActionSupport{ @Resource(name="userService") private UserService userService; /** * 保存用戶 */ public String saveUser() { User user = new User(); user.setAccount("admin"); user.setPassword("admin"); userService.saveEntity(user); return SUCCESS; } /** * 根據ID查找用戶 */ public String findUserById() { long id = 1L; User user = userService.getById(User.class, id); return SUCCESS; } }
@Controller用於將控制層的類標識為 Spring Bean。
6、在struts.xml添加action的配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <constant name="struts.objectFactory" value="spring" /> <constant name="struts.ui.theme" value="simple" /> <constant name="struts.action.extension" value="action" /> <package name="default" namespace="/" extends="struts-default"> <!-- 保存用戶 --> <action name="saveUser" class="userAction" method="saveUser"> <result>/WEB-INF/page/user/userList.jsp</result> </action> <!-- 根據ID查找用戶 --> <action name="findUserById" class="userAction" method="findUserById"> <result>/WEB-INF/page/user/userDetail.jsp</result> </action> </package> <!-- Add packages here --> </struts>
7、spring配置文件applicationContext.xml不再需要任何額外的配置。
8、ok,簡單的使用完畢。
