Spring3.0学习-注解模式下的Spring3+hibernate3+struts2-事务管理(xml模式和注解模式的事务注入+@Repository@Service@Transactional)
2016-10-31 01:14
573 查看
一、前言
最近一段时间学习了《Spring 实战(第3版)》的第5、6章,对Spring直接操作数据库有了一定的认识。由于书中前4章例子相对比较完整,学习起来还算顺利,第5、6章内容不是很多,但是涉及的技术迭代范围较广,例子也不是很完全,知识学习期间走了一些弯路,不过还好,总算是通过各种途径找到了最终想学的东西——注解模式下的Spring+Hibernate的基本使用,在完成Spring和hibernate的结合后,本文将加入struts2,这样一个SSH的小例子就算完成了。事实上,当我完成文章涉及的例子的时候,最深刻的感悟是,Spring起到了统领的作用,然后是bean,自动扫描或者声明,注入,事务管理,中间插件。
对于初次接触Spring的可以先看一下几篇文章
Spring 3.0 学习-环境搭建和三种形式访问
Spring 3.0 学习-DI 依赖注入_创建Spring 配置-使用一个或多个XML 文件作为配置文件,使用自动注入(byName),在代码中使用注解代替自动注入,使用自动扫描代替xml中bean
Spring3.0 学习-AOP面向切面编程_Spring AOP的XML配置模式
Spring3.0 学习-AOP面向切面编程_Spring AOP的注解模式即Aspectj模式
二、Spring3+Hibernate3注解模式下的结合
1、相关jar包。
如果jar包缺失或者版本不兼容,开发过程会变得十分纠结,所以务必注意版本问题;这里我把我自己用到的jar包贴出来,struts2、Spring3是从官网下载的,hibernate3是通过maven一点一点“凑出来的”,还有mysql的驱动jar包,此外,本文使用的jdk1.7版本。
2、数据源配置
我使用的是mysql数据库,数据库名称为 test,由于使用了hibernate自动建表,而且表只有两个字段,所以这里不再多说表结构。<!-- 定义数据源-注解配置 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!-- 初始化创建的数据库连接数 --> <property name="initialSize" value="${jdbc.initialSize}"/> <!-- 数据库连接池最大的连接数 --> <property name="maxActive" value="${jdbc.maxActive}"/> </bean>
3、sessionFactory配置
含义可以参考文章 http://www.cnblogs.com/lihaoyang/p/4853712.html<!-- 声明Hibernate 的 Session 工厂--> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">--> <property name="dataSource" ref="dataSource"/> <!-- model里含有具体的实体类若干 --> <property name="packagesToScan" value="stu.demo.model"/> <!-- 可以更换为下面这句 --> <!-- <property name="annotatedClasses"> <list> <value>stu.demo.model.Person</value> </list> </property> --> <property name="hibernateProperties"> <props> <prop key=" hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html --> </props> </property> </bean>
4、Spring具有较为完善的异常表达体系
将异常转化为Spring的表达方式,其实就一句配置文件<!-- 操作异常转化为Spring的表达方式 --> <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
5、transactionManager配置
事务管理器配置<!-- hibernate事物管理器的声明,txAdvice会调用,所以需要声明,如果使用其他的则直接更换即可,和代码是松耦合的 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
6、tx配置。通过切面将事务管理器织入到指定“接口的实现”
可以看介绍 http://wcp88888888.iteye.com/blog/12796036.1 xml配置
这里注意<aop:config>设置切点,可以是采取下面的限定到一个文件夹,但是为了同时实验xml配置和注解配置,我们使用了限定到一个java文件,本例符合下面事务切面配置的java文件只有两个。<!-- tx设置事物管理,当然还有其他的设置 ,指定管理者为id="transactionManager"的bean,其实不指定也可以Spring自己会注入但是id=transactionManager的这个bean必须声明--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save" propagation="REQUIRED"/> <tx:method name="*" propagation="SUPPORTS" read-only="false"/> </tx:attributes> </tx:advice> <!-- 设置切面,将事物管理通知给方法 -所有实现PersonService接口的方法,对于事务的意义而言--> <aop:config> <!-- 限定到一个java文件 --> <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..PersonService.*(..))"/> <!-- 限定到一个文件夹 --> <!--<aop:advisor advice-ref="txAdvice" pointcut="execution(* stu.demo.serviceImpl..*(..))"/>--> </aop:config>
6.2注解模式
Spring配置文件部分比较简单<!-- tx:advice和 切点的替代法-注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
java部分,需要注解@Transactional以及其他个性化设置
@Transactional(readOnly=false,isolation=Isolation.DEFAULT)
7、代码结构
本文代码结构包含,Dao接口类,Dao实现类(需注解@Repository),Service接口类,Service实现类(需注解@Service以及6.2注解模式下的@Transactional,调用Dao接口),Model类,Spring配置文件(自动注入,切面设置,bean声明,异常转化等),常量文件(数据库驱动等)和测试jave类。Person.java为实体类,本例演示保存实体对象到mysql数据库。
8、代码
Mode类:Person.javapackage stu.demo.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity(name="PERSON") @Table(name="PERSON") public class Person { private String username; private String password; @Id @Column(name="USERNAME",unique=true,nullable=false) public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @Column(name="PASSWORD") public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
Dao接口类:PersonDao.java
package stu.demo.dao; import stu.demo.model.Person; public interface PersonDao { //使用当前session完成数据库的相关操作 public void addPerson(Person person); }
Dao接口类:Person2Dao.java
package stu.demo.dao; import stu.demo.model.Person; public interface Person2Dao { public void addPerson(Person person); }
Dao接口实现类:PersonDaoImpl.java
package stu.demo.daoImpl; import org.hibernate.SessionFactory; import org.hibernate.classic.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import stu.demo.dao.PersonDao; import stu.demo.model.Person; @Repository public class PersonDaoImpl implements PersonDao { private SessionFactory sessionFactory; @Autowired public PersonDaoImpl(SessionFactory sessionFactory) { // TODO Auto-generated constructor stub this.sessionFactory=sessionFactory; } //获取当前session private Session currentSession(){ return sessionFactory.getCurrentSession(); } //使用当前session完成数据库的相关操作 public void addPerson(Person person){ currentSession().save(person); } }
Dao接口实现类:Person2DaoImpl.java
package stu.demo.daoImpl; import org.hibernate.SessionFactory; import org.hibernate.classic.Session; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import stu.demo.dao.Person2Dao; import stu.demo.model.Person; @Repository public class Person2DaoImpl implements Person2Dao { private SessionFactory sessionFactory; @Autowired public Person2DaoImpl(SessionFactory sessionFactory){ this.sessionFactory=sessionFactory; } public Session currentSession(){ return sessionFactory.getCurrentSession(); } /** * 保存新用户 */ public void addPerson(Person person) { // TODO Auto-generated method stub currentSession().save(person); } }
Service接口类:PersonService.java
package stu.demo.service; import stu.demo.model.Person; public interface PersonService { public void addPerson(Person person); }
Service接口类:Person2Service.java
package stu.demo.service; import stu.demo.model.Person; public interface Person2Service { public void addPerson(Person person); }
service接口实现类:PersonServiceImpl.java
package stu.demo.serviceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import stu.demo.dao.PersonDao; import stu.demo.model.Person; import stu.demo.service.PersonService; @Service public class PersonServiceImpl implements PersonService { @Autowired private PersonDao personDao; public void addPerson(Person person) { // TODO Auto-generated method stub personDao.addPerson(person); } }
service接口实现类:Person2ServiceImpl.java
package stu.demo.serviceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import stu.demo.dao.Person2Dao; import stu.demo.model.Person; import stu.demo.service.Person2Service; @Service @Transactional(readOnly=false,isolation=Isolation.DEFAULT) public class Person2ServiceImpl implements Person2Service { @Autowired private Person2Dao person2dao; public void addPerson(Person person) { // TODO Auto-generated method stub person2dao.addPerson(person); } }
常量配置
jdbc.properties
#jdbc settings jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=root jdbc.initialSize=5 jdbc.maxActive=10 #hibernate settings hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.show_sql=false hibernate.format_sql=false hibernate.hbm2ddl.auto=update
常量配置
application.properties
内容为空
Spring 配置文件
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?><!-- 一般化的Spring XML 配置 -->
<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:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:orm="http://www.springframework.org/schema/orm"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" >
<!-- 使用注解注入 -->
<context:component-scan base-package="stu.demo.daoImpl"/>
<context:component-scan base-package="stu.demo.serviceImpl"/>
<!-- 定义受环境影响易变的变量 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- 标准配置 -->
<value>classpath:config/application.properties</value>
<!-- 数据库配置 -->
<value>classpath:config/jdbc.properties</value>
</list>
</property>
</bean>
<!-- 定义数据源-注解配置 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!-- 初始化创建的数据库连接数 --> <property name="initialSize" value="${jdbc.initialSize}"/> <!-- 数据库连接池最大的连接数 --> <property name="maxActive" value="${jdbc.maxActive}"/> </bean>
<!-- 声明Hibernate 的 Session 工厂--> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">--> <property name="dataSource" ref="dataSource"/> <!-- model里含有具体的实体类若干 --> <property name="packagesToScan" value="stu.demo.model"/> <!-- 可以更换为下面这句 --> <!-- <property name="annotatedClasses"> <list> <value>stu.demo.model.Person</value> </list> </property> --> <property name="hibernateProperties"> <props> <prop key=" hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html --> </props> </property> </bean>
<!-- 操作异常转化为Spring的表达方式 --> <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- hibernate事物管理器的声明,txAdvice会调用,所以需要声明,如果使用其他的则直接更换即可,和代码是松耦合的 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
<!-- tx设置事物管理,当然还有其他的设置 ,指定管理者为id="transactionManager"的bean,其实不指定也可以Spring自己会注入但是id=transactionManager的这个bean必须声明--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save" propagation="REQUIRED"/> <tx:method name="*" propagation="SUPPORTS" read-only="false"/> </tx:attributes> </tx:advice> <!-- 设置切面,将事物管理通知给方法 -所有实现PersonService接口的方法,对于事务的意义而言--> <aop:config> <!-- 限定到一个java文件 --> <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..PersonService.*(..))"/> <!-- 限定到一个文件夹 --> <!--<aop:advisor advice-ref="txAdvice" pointcut="execution(* stu.demo.serviceImpl..*(..))"/>--> </aop:config>
<!-- tx:advice和 切点的替代法-注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
测试类:HibernatePersonDaoTest.java
package stu.demo.dao; import java.text.SimpleDateFormat; import java.util.Date; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.transaction.TransactionConfiguration; import stu.demo.model.Person; import stu.demo.service.Person2Service; import stu.demo.service.PersonService; @DirtiesContext @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations={"classpath:spring/applicationContext.xml"}) @TransactionConfiguration(transactionManager = "defaultTransactionManager",defaultRollback=false)//事务管理 public class HibernatePersonDaoTest { @Autowired private PersonService personService; @Autowired private Person2Service person2Service; /** * <tx:advice+切面 配置事务管理 */ @Test public void testaddPerson(){ SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss"); Person person=new Person(); person.setUsername("JecketOne"+sdf.format(new Date())); person.setPassword("123456"); personService.addPerson(person); } /** * <tx:annotation-driven 配置事务管理 */ @Test public void testaddPerson2(){ SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss"); Person person=new Person(); person.setUsername("JecketTwo"+sdf.format(new Date())); person.setPassword("123456"); person2Service.addPerson(person); } }
测试类运行结果:
看mysql数据库:
三、增加Struts2
接下来,我们将加入struts2的必要的代码,实现一个SSH为框架的web应用,仅仅保存新用户然后在另一个页面显示用户的名字。我们需要新加入一个jar包用户在spring中使用struts2
struts2-spring-plugin-2.2.3.1.jar
然后依次是controller类,也就是常说的action类,并且在Spring的配置文件中声明这个类为bean,或者使用“<context:component-scan”自动扫描注册为bean,
接着是struts.xml配置文件,有意思的是,在声明<action>标签中的class时,我们可以不写具体的action类的路径直到名字了,而是可以是这个action类在Spring
配置文件中的名字,如果是自动注册的话,就是类名的“非限定类名”,比如类名为PersonAction,其非限定类名就是personAction。
Spring中@Repository用于声明数据访问组件,这里用于声明Dao类的实现,@Service用于声明业务层的组件,@Controller用于声明控制层组件,@Componen是
三者的泛化,可以应用于任何层,在扫描时告诉Spring本标注类时一个bean。
Spring中@Autowired是注入,等同于byType;@Resource也是注入,等同于byName。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- Spring ApplicationContext配置文件的路径,可使用通配符,多个路径用,号分隔 此参数用于后面的Spring Context Loader --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext.xml</param-value> </context-param> <!-- struts2过滤器配置 --> <filter> <filter-name>MyFilter</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>FORWARD</dispatcher> <dispatcher>REQUEST</dispatcher> </filter-mapping> <listener> <description>Spring 刷新 Introspector 防止内存泄露</description> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <listener> <description>Spring ApplicationContext 载入</description> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <session-config> <session-timeout>30</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>
增加的两个jsp页面
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form method="post" action="<%=path %>/test/register.action"> 用户名:<input type="text" name="username"><br/> 密码:<input type="password" name="password"/><br/> <input type="submit" value="提交"> </form> </body> </html>
success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> 保存成功:<br/> 用户名:${person.username}<br/> </body> </html>
控制类/action类
PersonAction.java ,此类需(@Controller标注且在Spring配置文件设置自动扫描),或者(直接声明为bean)
package stu.demo.action; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; import stu.demo.model.Person; import stu.demo.service.PersonService; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; @SuppressWarnings("serial") @Controller public class PersonAction extends ActionSupport implements ModelDriven<Person> { private Person person; public Person getModel() { if(person==null){ person=new Person(); } return person; } @Autowired private PersonService personService; public String register(){ SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddhhmmss"); getModel().setUsername(sdf.format(new Date())+getModel().getUsername()); personService.addPerson(getModel()); ActionContext context=ActionContext.getContext(); Map<String, Object> session=context.getSession(); session.put("person", getModel()); return SUCCESS; } }
struts2的配置文件,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.i18n.encoding" value="UTF-8"/> <!-- 指定被struts2处理的请求后缀类型。多个用逗号隔开 --> <constant name="struts.action.extension" value="action"/> <!-- 当struts.xml改动后,是否重新加载。默认值为false(生产环境下使用),开发阶段最好打开 --> <constant name="struts.configuration.xml.reload" value="true"/> <!-- 是否使用struts的开发模式。开发模式会有更多的调试信息。默认值为false(生产环境下使用),开发阶段最好打开 --><!-- <constant name="struts.devMode" value="false"/> --><!-- 设置浏览器是否缓存静态内容。默认值为true(生产环境下使用),开发阶段最好关 闭 --><!-- <constant name="struts.serve.static.browserCache" value="false" /> --><!-- 包含的其他配置文件 --> <include file="struts/struts-method.xml"></include> </struts>
struts-method.xml
注意其中对class的两个注释
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <!-- struts-default-package --> <package name="test" extends="struts-default" namespace="/test"> <!--<action name="*" class="stu.demo.action.PersonAction" method="{1}">--> <!--在Spring中, PersonAction 已经被注册为bean了,可以使用其id来调用,声明为personAction,自动扫描的话为非限定类名personAction --> <action name="*" class="personAction" method="{1}"> <result name="success">/success.jsp</result> <result name="input">/index.jsp</result> </action> </package> </struts>
最后是Spring配置文件,其实相比上面的配置只是多了一个控制器类的bean声明/自动扫描声明,但是多了一些注释
applicationContext.xml
这个文件已经写到了web.xml中,在web项目启动的时候,会自动加载
'
<?xml version="1.0" encoding="UTF-8"?><!-- 一般化的Spring XML 配置 -->
<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:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:orm="http://www.springframework.org/schema/orm"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/orm http://www.springframework.org/schema/orm/spring-orm-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" >
<!-- 使用注解注入 @Autowired-byType和@Resource-byName-->
<context:component-scan base-package="stu.demo.daoImpl"/><!--@Repository-->
<context:component-scan base-package="stu.demo.serviceImpl"/><!-- @Service 事务注入@Transactional(readOnly=false,isolation=Isolation.DEFAULT) -->
<!-- Controller类注册为bean,也可以显示的写为
<bean id="personAction" class="stu.demo.action.PersonAction"/> 可以加scope
-->
<context:component-scan base-package="stu.demo.action"/><!-- @Controller-->
<!--<bean id="personAction" class="stu.demo.action.PersonAction"/>
--><!-- 定义受环境影响易变的变量 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- 标准配置 -->
<value>classpath:config/application.properties</value>
<!-- 数据库配置 -->
<value>classpath:config/jdbc.properties</value>
</list>
</property>
</bean>
<!-- 定义数据源-注解配置 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" > <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <!-- 初始化创建的数据库连接数 --> <property name="initialSize" value="${jdbc.initialSize}"/> <!-- 数据库连接池最大的连接数 --> <property name="maxActive" value="${jdbc.maxActive}"/> </bean>
<!-- 声明Hibernate 的 Session 工厂--> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <!--<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">--> <property name="dataSource" ref="dataSource"/> <!-- model里含有具体的实体类若干 --> <property name="packagesToScan" value="stu.demo.model"/> <!-- 可以更换为下面这句 --> <!-- <property name="annotatedClasses"> <list> <value>stu.demo.model.Person</value> </list> </property> --> <property name="hibernateProperties"> <props> <prop key=" hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop><!--自动建表 http://www.cnblogs.com/feilong3540717/archive/2011/12/19/2293038.html --> </props> </property> </bean>
<!-- 操作异常转化为Spring的表达方式 --> <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- hibernate事物管理器的声明,txAdvice会调用,所以需要声明,如果使用其他的则直接更换即可,和代码是松耦合的 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean>
<!-- tx设置事物管理,当然还有其他的设置 ,指定管理者为id="transactionManager"的bean,其实不指定也可以Spring自己会注入但是id=transactionManager的这个bean必须声明--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save" propagation="REQUIRED"/> <tx:method name="*" propagation="SUPPORTS" read-only="false"/> </tx:attributes> </tx:advice> <!-- 设置切面,将事物管理通知给方法 -所有实现PersonService接口的方法,对于事务的意义而言--> <aop:config> <!-- 限定到一个java文件 --> <aop:advisor advice-ref="txAdvice" pointcut="execution(* *..PersonService.*(..))"/> <!-- 限定到一个文件夹 --> <!--<aop:advisor advice-ref="txAdvice" pointcut="execution(* stu.demo.serviceImpl..*(..))"/>--> </aop:config>
<!-- tx:advice和 切点的替代法-注解--> <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
启动服务器:
访问http://localhost:8085/SpringHibernate/ (http://localhost:8085/SpringHibernate/)
点击提交
再看数据库的表,在项目启动时,自动建表,提交后,数据库增加一条数据
后期使用maven实现的ssh的例子
完整的ssh代码请查看 https://github.com/Bestcxy/SSH-ajax-axis2-maven-log4j-redis如果你还没有加入github 请先阅读 http://blog.csdn.net/bestcxx/article/details/63687217
2017年06月12日补充
junit 测试方法可以控制回滚需继承public class TClassServiceTest extends AbstractTransactionalJUnit4SpringContextTests{
相关文章推荐
- Spring 3.0 学习-DI 依赖注入_创建Spring 配置-使用一个或多个XML 文件作为配置文件,使用自动注入(byName),在代码中使用注解代替自动注入,使用自动扫描代替xml中bea
- spring将service添加事务管理,在applicationContext.xml文件中的设置
- Spring配置事务管理,service端通过@Transactional注解
- 关于spring3.0 后的 事务注解管理指定数据源问题
- Spring配置事务管理,service端通过@Transactional注解
- 如何用Spring将Service注入到Servlet中(注解模式)
- Spring3.0 学习-AOP面向切面编程_Spring AOP的注解模式即Aspectj模式
- spring框架学习(七)spring管理事务方式之xml配置
- spring学习(十一)—事务管理(注解方式实现)
- Spring学习-34:Spring中的事务管理之声明式事务(基于注解)
- Spring 下事务管理-使用AOP @Transactional注解管理
- Spring 下事务管理-使用AOP @Transactional注解管理
- spring中事务的管理基于xml和注解,以及spring在web中应用
- Spring学习之事务注解@Transactional
- 如何用Spring将Service注入到Servlet中(注解模式)
- Spring的事务管理机制学习(设计模式之策略模式)
- java事务学习笔记(七)--像Spring一样使用Transactional注解(Annotation)
- Spring学习笔记(17)----使用Spring注解方式管理事务
- Spring第六讲学习笔记,使用注解开发。Repository,Service,Controller
- spring框架学习(八)spring管理事务方式之注解配置