Spring經常使用配置

----------------------------------------------------------------------------------------------
[版權申明:本文系做者原創,轉載請註明出處
文章出處:http://blog.csdn.net/sdksdk0/article/details/52471101
做者:朱培      ID:sdksdk0      郵箱: zhupei@tianfang1314.cn   
--------------------------------------------------------------------------------------------前端

本文主要分享的是spring的基礎,經常使用配置,都是很是重要的內容,理論+實踐,文末配有案例源碼下載連接。spring是開發javaee查詢很是重要的一個框架,能夠爲後續使用springMVC打下良好的基礎,其實主要的就是一些配置文件,須要哪些jar包,咱們應該如何去配置,本文都有很是詳細的闡述。經過使用spring整合hibernate、struts整合spring來作的SSH框架也是很是經典的一個開發模式,做爲開發者都應該努力把這一部分的內容掌握,固然了,對於配置文件也不須要你一個個類的去背下來,只要記得去哪裏找到這個類的配置,知道這個類有哪些方法是咱們能夠用的就好。同時對於不一樣的版本有的類方法的使用也是存在稍許差別的,學會多總結,多運用,多思考。java

 

 

簡介

什麼是:Springmysql

Spring是一個分層的JavaSE/EE full-stack(一站式) 輕量級開源框架。 輕量級:依賴其餘內容教小,使用資源消耗也少。 核心:控制反轉Ioc和麪向切面AOP。 spring生成的東西叫作bean.git

 

spring是J2EE應用程序框架,是輕量級的IoC和AOP的容器框架,主要是針對javaBean的生命週期進行管理的輕量級容器。Spring包含7大模塊,每一個模塊能夠單獨使用、也能夠結合起來使用;可是在實際開發過程當中,通常須要結合Struts、Hibernate來使用。

 

體系結構

核心組件:beans、core、context、expressiongithub

第一個實例

loc控制反轉 一、導入jar包 二、spring核心配置文件 三、使用api得到對象實例web

DI依賴注入

一個類中使用了另外一個類,就稱爲兩個類存在依賴關係。從spring得到service實現類(ioc),spring自動將dao的實現類注入給service。spring

service提供setter方法。sql

BeanFactory和ApplicationContextexpress

採用延遲加載,當第一次調用getBean方法時初始化,Application在加載完成配置文件以後進行初始化。apache

裝配bean基於xml

bean的三種實例化方式

一、使用默認構造

<!-- 建立dao -->
<bean id="bookDaoId"  class="cn.tf.demo2.BookDaoImpl"></bean>
<!-- 建立service -->
<bean id="bookServiceId"  class="cn.tf.demo2.BookServiceImpl">
    <!-- 使用property來完成注入,name表示當前屬性名稱,ref表示配置文件中另外一個bean的引用 -->
    <property name="bookDao" ref="bookDaoId"></property>
</bean>

二、靜態工廠 public class MyFactory {

public static PersonDao  createPersonDao(){
        return new PersonDaoImpl(); 
    }
}

配置文件中:

<bean id="personDaoId"   class="cn.tf.demo4.MyFactory"  factory-method="createPersonDao"></bean>

三、實例工廠 使用工廠以前須要先建立

//實例工廠
public PersonDao  createPersonDao(){
    return new PersonDaoImpl(); 
}

配置文件:

<bean id="myFactory" class="cn.tf.demo4.MyFactory"  >
</bean>

<bean id="personDaoId" factory-bean="myFactory"  factory-method="createPersonDao"></bean>

bean的種類

普通bean:以前使用的全部bean,通常很經常使用,例如service和dao等

工廠bean:spring提供接口,FactoryBean,一個特殊的bean,具備Factory工廠,用於生產特定的Bean的bean。例如:ProxyFactoryBean用於生產代理對象的一個bean。

id屬性和name屬性:

id能夠自動提示,名稱不能重複。 name若是沒有配置id,name也可使用,能夠編寫多個名稱,使用逗號分隔。

bean的做用域

spring默認狀況下建立的bean都是單例的。

 

取值: singleton:單例。 prototype:多例。

bean的生命週期

  1. 初始化
  2. setter 屬性注入
  3. 得到配置bean名稱:replyDaoId,必須實現接口:BeanNameAware
  4. 得到spring容器,至關於TestApp new ClassPath... , 必須實現接口:ApplicationContextAware --- 也能夠實現接口:BeanFactoryAware
  5. 初始化以前執行
  6. 初始化前屬性設置
  7. 初始化方法,須要在xml配置 <bean init-method='' >
  8. 初始化以後執行
  9. save 方法

-

<bean id="replyDaoId" class="cn.tf.demo6.ReplyDao"  
    init-method="replyInit"
    destroy-method="replyDestory">
    <property name="username"  value="張三"></property>
</bean>

<!-- 配置後處理bean -->
<bean  class="cn.tf.demo6.MyBeanPostProcessor"></bean>

依賴注入

手工裝配:使用xml:一、構造方法注入;二、setter方法注入;三、接口注入

<bean id="categoryId" class="cn.tf.demo7.a.Category">
    <!-- 描述構造方法的一個參數
        index:參數的索引
        type:參數的類型
        value:參數的值
        ref:參數的值的引用對象
     -->        
    <constructor-arg index="0" type="java.lang.String" value="123"></constructor-arg>
    <constructor-arg index="1" type="java.lang.Integer" value="456"></constructor-arg>
</bean>

自動裝配:框架整合時:

byType:按類型裝配 
byName:按名稱裝配
constructor按構造
auto 不肯定裝配。

p命名空間

簡化set方法注入

setter方法:

<bean id="" class="" >
<property name="username" value="make" >
<property name="address" ref="addressId" >

p命名空間:

xmlns:p="http://www.springframework.org/schema/p"

<bean id="companyId" class="cn.tf.demo7.b.Company"  p:name="指令匯科技"  p:address-ref="addressId"></bean>
<bean id="addressId"  class="cn.tf.demo7.b.Address"  p:addr="湖南衡陽"></bean>

SpEL表達式

spring表達式語言。

value="#{表達式}"

<bean id="studentId" class="cn.tf.demo7.c.Student">
        <property name="teacher"  value="#{teacherId}"></property>
        <property name="pi"  value="#{T(java.lang.Math).PI}"></property>
</bean>

<bean id="teacherId"  class="cn.tf.demo7.c.Teacher"  >
        <property name="tname"  value="#{'abc'.toUpperCase()}"></property>
</bean>

集合注入

常見的5種集合:

private String[] arrayData;
private List<String> listData;
private Set<String> setData;
private Map<String,String> mapData;
private Properties propsData;

配置文件中:

<bean id="collbeanId" class="cn.tf.demo7.d.CollBean">
    <!-- 數組 -->
    <property name="arrayData">
        <array>
            <value>數組1</value>
            <value>數組2</value>
            <value>數組3</value>
        </array>
    </property>
    <!-- List集合 -->
    <property name="listData">
        <list>
            <value>List集合1</value>
            <value>List集合1</value>
            <value>List集合1</value>
        </list>
    </property>

    <!-- Set集合 -->
    <property name="setData">
        <set>
            <value>set集合1</value>
            <value>set集合2</value>
            <value>set集合3</value>
        </set>
    </property>

    <!-- map集合 -->
    <property name="mapData">
        <map>
            <entry  key="aa"  value="00"></entry>
            <entry>
                <key><value>bb</value></key>
                <value>11</value>
            </entry>
        </map>
    </property>

    <!-- properties對象 -->
    <property name="propsData">
        <props>
            <prop key="aa">00</prop>
            <prop key="bb">11</prop>
        </props>
    </property>
</bean>

裝配bean基於註解

使用註解類用於取代xml配置文件,優勢在於:xml配置少,使用註解配置信息簡化。不足之處在於硬編碼。

@Component組件,用於取代

@Component(value = "orderDaoId")

@Repository 修飾dao層

@Service 修飾service層

Controller 修飾web層

方案1:

@AutoWired 自動注入,默認按照類型
    能夠修飾在字段上
    也能夠修飾在setter方法上
    缺點:若是同一個接口,有兩個實現類,就會存在衝突

@Qualifier 修改AutoWired匹配,將按照名稱匹配。

方案2:

@Resource 能夠完成 @AutoWired 和 @Qualifier 功能 例如:@Resource("userDaoId") 按照名稱匹配

@PostConstruct 初始化
 @PreDestroy 銷燬

@Scope 做用域

使用註解,必須將「被註解修飾的類」交予spring進行掃描。

<context:component-scan base-package="類所在包名">

整合junit

導入spring-test-4.2.5.RELEASE.jar

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:cn/tf/demo9/beans.xml")
public class TestApp {
@Autowired
private UserDao userDao;

@Test
public void test1(){
    userDao.save(); 
}

在classpath中加載註解文件

xml和註解混搭使用

<!-- 使 注入的註解可使用 -->
 <context:annotation-config></context:annotation-config>

<!-- 全部的bean都在xml配置 
    全部的依賴都是註解
-->
<bean id="userDaoId" class="cn.tf.demo10.UserDaoImpl"></bean>
<bean id="userServiceId" class="cn.tf.demo10.UserServiceImpl"></bean>
<bean id="userActionId" class="cn.tf.demo10.UserAction"></bean>

AOP

面向切面編程:採用橫向抽取機制,取代了傳統縱向繼承體系重複性代碼。

AOP的應用:性能監視、事務管理、安全檢查、緩存等。

target:目標類,須要被代理的類,也是須要被加強的類。

JoinPoint:鏈接點,須要被攔截點,spring中鏈接點就是方法,及目標類全部方法。 PointCut:切入點,已經被攔截的鏈接點,有哪些鏈接點須要被加強。 Advice:通知/加強,加強的內容。 Weaving:織入,用加強Advice應用目標類Target,生成代理對象過程。 proxy:代理。 aspect:切面,通知advice與切入點Point

spring AOP底層

接口+實現類:使用jdk的動態代理。

實現類:使用的是cglib(字節碼加強)

字節碼加強框架,不用使用接口,在運行時,動態的建立目標類的子類,目標類不能使用final。

目標類:

public class BookService {
public void addBook(){
    System.out.println("cglib addBook");
}

public void updateBook(){
    System.out.println("cglib updateBook");
}
}

切面類:

public class MyAspect {

public void before(){
    System.out.println("以前執行");
}
public void after(){
    System.out.println("以後執行");
}
}

工廠:

public static Object getBean(){
    final BookService  bookService=new BookService();
    //切面類
    final MyAspect myAspect=new MyAspect();
    //生成代理類。代理類是目標類的子類
    //核心類
    Enhancer enhancer=new Enhancer();
    //肯定父類
    enhancer.setSuperclass(bookService.getClass());
    //設置處理
    enhancer.setCallback(new MethodInterceptor() {

        @Override
        public Object intercept(Object proxy, Method method, Object[] args,
                MethodProxy methodProxy) throws Throwable {
            //執行目標類的方法
            myAspect.before();
            Object obj=method.invoke(bookService, args);
            methodProxy.invokeSuper(proxy, args);
            myAspect.after();
            return obj;
        }
    }); 
    //建立代理類
    Object proxyObj=enhancer.create();
    return proxyObj;

}

aop通知類型

aop是一種思想,有aop聯盟提出,spring對aop的規範進行支持。

5種通知: 前置通知:在目標方法執行以前實施加強。 後置通知:在執行目標後實施加強。 環繞通知:在方法執行先後實施加強。 異常拋出通知:在方法拋出異常後實施加強。 引介通知:在目標類中添加一些新的方法和屬性。

spring工廠bean--半自動

切面類:須要實現接口, MethodInterceptor 環繞通知

public class MyAspect implements MethodInterceptor {

@Override
public Object invoke(MethodInvocation mi) throws Throwable {
    System.out.println("前");
    //執行目標方法
    Object obj = mi.proceed();
    System.out.println("後");
    return obj;
}
}

配置文件:

<bean id="personServiceId" class="cn.tf.demo3.PersonServiceImpl"></bean>

<!-- 切面類,含通知 -->
<bean id="myAspect" class="cn.tf.demo3.MyAspect" ></bean>

<!-- 
        ProxyFactoryBean 用於生產代理類一個特殊的工廠bean
        proxyInterfaces 用於肯定須要實現接口
        interceptorNames 用於肯定通知實現類,須要提供的bean名稱
        target 用於肯定代理類bean名稱
 -->

<!-- 代理類 -->
<bean id="personServiceProxyId"  class="org.springframework.aop.framework.ProxyFactoryBean">
    <!-- 肯定接口 -->
    <property name="proxyInterfaces" value="cn.tf.demo3.PersonService"></property>
    <!-- 肯定通知 -->
    <property name="interceptorNames"  value="myAspect"></property>
    <!-- 肯定目標類 -->
    <property name="target"  ref="personServiceId"></property>
    <!-- 強制cglib -->
    <property name="optimize" value="true"></property>

</bean>

AOP全自動

使用AspectJ的表達式

 

<!-- 切面類,含通知 -->
<bean id="myAspect" class="cn.tf.demo4.MyAspect" ></bean>
<!-- aop編程 -->
<aop:config>
    <!-- 切入點 -->
    <aop:pointcut expression="execution(* cn.tf.demo4.*ServiceImpl.*(..))" id="myPointCut"/>
    <!-- 一個特殊的切面  ,包含一個切入點和一個通知-->
    <aop:advisor advice-ref="myAspect"  pointcut-ref="myPointCut"/>
</aop:config>

aspectJ切入點表達式

導入jar包: aspectJ、springaop、aop聯盟規範、

一、execution

execution:匹配方法的執行 格式:execution(修飾符 返回值類型 包.類名.方法名(參數列表)throws 異常)

修飾符:public|private

返回值類型:String|void|*

包:cn.tf.service --指定包 cn.tf.pm..Service --指定模塊 cn.tf.pm..service.. --表示當前目錄以及子目錄

類名:UserService --指定名稱 *Service --以Service結尾

方法名:save --執行方法名稱 add* --add開頭

參數列表: () --無參 (int) --參數整形 (String,int) --兩個參數 (..) --參數任意

execution(* cn.tf..service...*(..))

二、within 肯定包或者子包 within(cn.tf.pm.*.service..)

三、this 匹配實現接口的代理類 this(cn.tf.pm.user.service.UserService)

四、taeget 目標類

五、args 參數列表

六、bean

通知類型

前置通知[Before advice]:在鏈接點前面執行,前置通知不會影響鏈接點的執行,除非此處拋出異常。

正常返回通知[After returning advice]:在鏈接點正常執行完成後執行,若是鏈接點拋出異常,則不會執行。

異常返回通知[After throwing advice]:在鏈接點拋出異常後執行。

返回通知[After (finally) advice]:在鏈接點執行完成後執行,不論是正常執行完成,仍是拋出異常,都會執行返回通知中的內容。

環繞通知[Around advice]:環繞通知圍繞在鏈接點先後,好比一個方法調用的先後。這是最強大的通知類型,能在方法調用先後自定義一些操做。環繞通知還須要負責決定是繼續處理join point(調用ProceedingJoinPoint的proceed方法)仍是中斷執行。

聲明通知類型

1 前置通知 , 目標方法以前執行。
                * 第一個參數爲JoinPoint,能夠得到目標方法名等。
            <aop:before method="myBefore" pointcut-ref="myPonitCut"/>
            2 後置通知,目標方法以後執行,能夠得到返回值。 經過「returning」屬性配置第二個參數的名稱,得到返回值的,類型必須Object
                * 第一個參數爲:JoinPoint
                * 第二個參數爲:Object xxx
            <aop:after-returning method="myAfterReturning" pointcut-ref="myPonitCut" returning="xxx"/>
            3 環繞通知, 目標方法先後
                方法要求:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
                執行目標方法:joinPoint.proceed();
            <aop:around method="myAround" pointcut-ref="myPonitCut"/>
            4 拋出異常通知,目標方法出現異常時才執行。經過「throwing」屬性配置第二個參數的名稱,得到具體的異常信息,類型必須是Throwable
                * 第一個參數爲:JoinPoint
                * 第二個參數爲:Throwable e
            <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPonitCut" throwing="e"/>

切面類:

public void myBefore(JoinPoint  joinPoint){
    System.out.println("前置通知"+joinPoint.getSignature().getName());
}

public void myAfterReturning(JoinPoint joinPoint,Object xxx){
    System.out.println("後置通知, 返回值:" + xxx);
}

public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{

    System.out.println("前");
    //必須執行目標方法
    Object obj = joinPoint.proceed();

    System.out.println("後");
    return obj;
}

public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
    System.out.println("拋出異常通知, " + e.getMessage());
}

public void myAfter(){
    System.out.println("最終");
}

配置文件:

<aop:config>
    <aop:aspect  ref="myAspect">
        <aop:pointcut expression="execution(* cn.tf.demo5.*.*(..))" id="myPointCut"/>
        <!-- 聲明通知類型 -->
        <aop:before method="myBefore"  pointcut-ref="myPointCut"/> 
        <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="xxx"/>
        <aop:around method="myAround"  pointcut-ref="myPointCut" />
        <aop:after-throwing method="myAfterThrowing"  pointcut-ref="myPointCut"  throwing="e"/>
        <aop:after method="myAfter"  pointcut-ref="myPointCut"/>


    </aop:aspect>
</aop:config>

基於註解

若是使用註解進行aop開發,必須進行aspectj自動代理。

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

通知註解:

@Before @AfterReturning @Around @AfterThrowing @After

@Component
@Aspect
public class MyAspect {

@Before("myPointCut()")
public void myBefore(JoinPoint  joinPoint){
    System.out.println("前置通知"+joinPoint.getSignature().getName());
}

@AfterReturning(value="execution(* cn.tf.demo6.*.*(..))",returning="xxx")
public void myAfterReturning(JoinPoint joinPoint,Object xxx){
    System.out.println("後置通知, 返回值:" + xxx);
}

@Around("myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{

    System.out.println("前");
    //必須執行目標方法
    Object obj = joinPoint.proceed();

    System.out.println("後");
    return obj;
}

@AfterThrowing(value="myPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
    System.out.println("拋出異常通知, " + e.getMessage());
}
@After("myPointCut()")
public void myAfter(){
    System.out.println("最終");
}
//用來聲明切入點表達式,在通知中經過方法名來得到,至關於調用方法
@Pointcut("execution(* cn.tf.demo6.*.*(..))")
private void myPointCut(){

}
}

配置文件:

<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    "> <!-- bean definitions here -->


    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>                 
    <!-- 掃描註解 -->
    <context:component-scan base-package="cn.tf.demo6"></context:component-scan>
</beans>

JDBC模板

導入spring中的jdbc,tx,c3p0,dbcp

屬性文件:jdbcInfo.properties

jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/dbone
jdbc.user=zp
jdbc.password=a

在spring的配置文件中配置:

<!-- 加載properties文件 -->
<context:property-placeholder location="classpath:cn/tf/jdbc/d/jdbcInfo.properties"/>

<!-- 配置數據源 
    若是properties文件已經被加載,能夠經過 ${key}得到配置文件中內容
-->
<bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

<!-- 配置dao -->
<bean id="userDaoId" class="cn.tf.jdbc.d.UserDao">
    <property name="dataSource" ref="dataSourceId"></property>
</bean>

dao的配置能夠依據實際狀況寫。

事務管理

一組業務操做,要麼所有成功,要麼所有失敗。

ACID:原子性、一致性、隔離型、持久性 隔離問題:髒讀、不可重複讀、虛讀

隔離級別:讀未提交、讀已提交、可重複讀、串行化

jdbc事務操做:
try{
    //得到鏈接
    conn=DriverManage...
    //開啓事務
    conn.setAutoCommit(false);
savepoint=conn.setSavepoint();

conn.commit();

}catch(){
if(savepoint==null){
    //回滾
    conn.rollback();

}else{
    conn.rollback(savepoint);
conn.commit();
}

}finally{
    //釋放
    conn.close();
}

Spring的事務

spring是基於aop進行事務管理的,導入jar包:spring-tx...

PlatformTransactionManager:平臺事務管理器,spring的基本操做都必須izai事務管理器的平臺上進行操做。 TransactionStatus:事務狀態,用於記錄事務狀態,方便在事務管理器平臺上,進行事務操做。 
TransactionDefinition:事務定義,事物詳情說明,

核心組件詳解

平臺事務管理器

JDBC、Hibernate、Mybatis、JPA都具備本身的事務管理器。

導入jar包:spring-jdbc... spring-orm...

事務管理器: DataSourceTransactionManager , JDBC事務管理器 HibernateTransactionManager , hibernate 事務管理器

經過事務管理器去解析事務詳情去得到事務狀態,經過狀態管理事務。

事務狀態

是不是新的事務、是否有保存點、設置了回滾、是否回滾、是否已經完成、刷新狀態同步

事務詳情:

名稱、是否只讀、得到超時時間、隔離級別、傳播行爲

傳播行爲:

PROPAGATION_REQUIRED, required : 默認 支持當前事務,A若是已經在事務中,B將直接使用A中事務。 若是不存在建立新的,A不在事務中,B將建立新的。

PROPAGATION_SUPPORTS supports : 支持當前事務,A若是已經在事務中,B將直接使用A中事務。 使用非事務執行,A不在事務中,B將也不使用事務執行。

PROPAGATION_MANDATORY mandatory : 支持當前事務,A若是已經在事務中,B將直接使用A中事務。 若是沒有事務將拋出異常,A不在事務中,B將拋異常。

PROPAGATIONREQUIRESNEW ,requires new : 建立新的。若是A沒有,B將建立新的。 掛起以前的。若是A有事務,B將掛起A的事務,建立新的。

PROPAGATIONNOTSUPPORTED , not supported: B將以非事務執行,若是A已經在事務中,將A事務掛起。

PROPAGATION_NEVER ,never B將以非事務執行,若是A已經在事務中,B將拋異常。

PROPAGATION_NESTED nested : 將採用嵌套事務執行。底層使用保存點Savepoint

採用配置的方式去設置「事務詳情」,spring經過事務管理器去管理事務。

案例:轉帳

半自動事務

使用工廠Bean生成代理、 設置事務管理代碼、設置事務管理器 、設置接口、設置目標、設置事務屬性(事務詳情)

配置文件:

<!-- 事務管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="DataSource"  ref="dataSource"></property>
</bean>

<!-- 代理對象,用於生產事務的代理對象 -->
<bean id="accountServiceProxy"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"  ref="txManager"></property>
    <!-- 接口 -->
    <property name="proxyInterfaces" value="cn.tf.service.AccountService"></property>
    <!-- 目標類 -->
    <property name="target" ref="accountService"></property>
    <!-- 事務屬性 -->
    <property name="transactionAttributes">
        <props>
            <prop  key="transfer">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

使用AOP

<!-- 事務管理器 -->
<bean  id="txManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource"  ref="dataSource"></property>
</bean>

<!-- 配置事務詳情 -->
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
        <!-- <tx:method> 肯定事務詳情配置
                name : 肯定方法名稱
                    transfer 肯定名稱
                    add*    add開頭
                    *   任意
                propagation 傳播行爲
                isolation 隔離級別
                read-only="false" 是否只讀
                rollback-for="" 指定異常回滾(-)
                no-rollback-for="" 指定異常提交(+)
            經典應用:開發中規定
                <tx:method name="add*"/>
                <tx:method name="update*"/>
                <tx:method name="delete*"/>
                <tx:method name="find*" read-only="true"/> -->
        <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
    </tx:attributes>
</tx:advice>

<!-- aop,將通知應用 目標類 -->
<aop:config>
    <aop:pointcut expression="execution(* cn.tf.service..*.*(..))" id="myPointcut"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/>
</aop:config>

基於註解

添加註解:@Transactional,能夠修飾在類或者方法上

在xml中配置事務管理器,並交由spring。

<!-- 事務管理器 -->
<bean  id="txManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource"  ref="dataSource"></property>
</bean>
<!-- 使用註解 -->
<tx:annotation-driven  transaction-manager="txManager"/>

web開發

導入jar包,spring-web...

在web.xml中配置:

<!-- 經過 servletContext 初始化參數設置xml位置 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<!-- spring 監聽器 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

在servlet的post方法中:

//spring 加容器存在 ServletContext中, sc.setAttribute(name, object)
    ServletContext sc = this.getServletContext();
    ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(sc);
    UserService userService = (UserService) ac.getBean("userService");

在applicationContext.xml中

<bean id="userService"  class="cn.tf.service.UserService"></bean>

SSH整合

jar包

配置文件: 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:context="http://www.springframework.org/schema/context"
   xmlns:aop="http://www.springframework.org/schema/aop"
   xmlns:tx="http://www.springframework.org/schema/tx"
   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
                       http://www.springframework.org/schema/aop 
                       http://www.springframework.org/schema/aop/spring-aop.xsd
                       http://www.springframework.org/schema/tx 
                       http://www.springframework.org/schema/tx/spring-tx.xsd">

</beans>

hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">
    com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
    jdbc:mysql://localhost:3306/dbone?useUnicode=true&amp;characterEncoding=UTF-8
</property>
<property name="hibernate.connection.username">zp</property>
<property name="hibernate.connection.password">a</property>
<property name="hibernate.dialect">
    org.hibernate.dialect.MySQL5Dialect
</property>

<!-- 3 sql -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>

<!-- 4 語句ddl -->
<property name="hibernate.hbm2ddl.auto">update</property>

<!-- 5 取消bean校驗 -->
<property name="javax.persistence.validation.mode">none</property>

<!-- 6 綁定session -->
<property name="hibernate.current_session_context_class">
    thread
</property>


<!-- 添加映射 -->
<mapping resource="cn/tf/domain/User.hbm.xml" />


</session-factory>
</hibernate-configuration>

User.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.tf.domain.User" table="t_user">
    <id name="id">
        <generator class="native"></generator>
    </id>
    <property name="username"></property>
    <property name="password"></property>
</class>
</hibernate-mapping>

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.devMode" value="true" />
<!-- struts標籤模板 -->
<constant name="struts.ui.theme" value="simple"></constant>

<package name="default" namespace="/" extends="struts-default">

</package>
</struts>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
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_3_0.xsd">
<!-- 肯定xml文件位置 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring監聽器,加載xml文件 -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- struts 前端控制器 -->
<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>
</web-app>

spring整合hibernate

有cfg.xml

使用Hibernate模板

<bean  id="userService"  class="cn.tf.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao"  class="cn.tf.dao.impl.UserDaoImpl">
    <property name="hibernateTemplate"  ref="hibernateTemplate"></property>
</bean>

<bean id="hibernateTemplate"  class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory"  ref="sessionFactory"></property>
</bean>

session工廠 ,特殊的bean生成SessionFactory加載配置文件
<bean id="sessionFactory"  class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocations"  value="classpath:hibernate.cfg.xml"></property>
</bean>

事務管理
<bean id="txManager"  class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory"  ref="sessionFactory"></property>
</bean>

 事務詳情 
<tx:advice  id="txAdvice"  transaction-manager="txManager">
    <tx:attributes>
        <tx:method name="add*"/>
        <tx:method name="update*"/>
        <tx:method name="delete*"/>
        <tx:method name="find*"  read-only="true"/>
    </tx:attributes>
</tx:advice>

<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.tf.service..*.*(..))"/>
</aop:config>

無cfg.xml

<!-- 1 service層 -->
<bean id="userService" class="cn.tf.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>
<!-- 2 dao 層 -->
<bean id="userDao" class="cn.tf.dao.impl.UserDaoImpl">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 3.1 加載properties配置文件 -->
<context:property-placeholder location="classpath:jdbcInfo.properties"/>
<!-- 3.2 數據源(c3p0)-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driverClass}"></property>
    <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>

<!-- 4 session工廠 
    * LocalSessionFactoryBean 特殊bean生成 SessionFactory
-->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <!-- 4.1 配置數據源 -->
    <property name="dataSource" ref="dataSource"></property>
    <!-- 4.2 hibernate 特有設置 -->
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="javax.persistence.validation.mode">none</prop>
        </props>
    </property>
    <property name="mappingDirectoryLocations" value="classpath:cn/tf/*"></property>
</bean>

<!-- 5 事務管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>

<!-- 5.2 事務詳情 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*"/>
        <tx:method name="update*"/>
        <tx:method name="delete*"/>
        <tx:method name="find*" read-only="true"/>
    </tx:attributes>
</tx:advice>

<!-- 5.3 aop 事務通知 應用 切入點 -->
<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* cn.tf.service..*.*(..))"/>
</aop:config>

struts整合spring

在applicationContext.xml中配置:

<bean id="userAction"  class="cn.tf.action.UserAction" scope="prototype">
    <property name="userService" ref="userService"></property>
</bean>

在struts.xml中

<package name="default" namespace="/" extends="struts-default">
    <action name="userAction_*" class="userAction" method="{1}">
        <result name="add">/success.jsp</result>
    </action>   
</package>

註解開發

配置掃描註解

<bean id="hibernateTemplate"  class="org.springframework.orm.hibernate3.HibernateTemplate">
    <property name="sessionFactory"  ref="sessionFactory"></property>
</bean>

<context:component-scan base-package="cn.tf"></context:component-scan>

配置事務管理器

<!-- 5 事務管理 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 5.2 註釋事務 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

struts的配置中:

@Namespace("/")  
@ParentPackage("struts-default")  

public class UserAction extends ActionSupport  implements ModelDriven<User>{

private User user=new User();
@Autowired
private UserService userService;

@Override
public User getModel() {
    return user;
}

public void setUserService(UserService userService) {
    this.userService = userService;
}
@Action(value="userAction_add" ,results=@Result(name="add",location="/success.jsp"))
public String add(){
    this.userService.addUser(user);
    return "add";
}

}

 

 

本文中使用的案例源碼:

https://github.com/sdksdk0/springDemo1  (包含bean裝配,scope做用域,spring表達式,spring生命週期,註解配置等)

https://github.com/sdksdk0/springDemo2  (包括AOP、aspectJ切入點表達式、jdbc模板等)

https://github.com/sdksdk0/springDemo3  (包含事務管理、轉帳案例、spring整合hibernate,struts整合spring等)

相關文章
相關標籤/搜索