Spring詳細教程

Spring學習總結----

1、導入Spring必須的jar包

2、簡單示例入門注入一個User

1.編寫User實體類java

複製代碼
package test.Spring.helloworld;

import java.util.List;
import java.util.Map;

public class User {
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private int id;
    private String name;
    
}
複製代碼

2.編寫Spring配置文件,類型爲xml,文件名能夠自定義mysql

複製代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd" 
        >
    
      <bean id="User" class="test.Spring.helloworld.User">
        <property name="id" value="1"></property>
        <property name="name" value="jayjay"></property>
    </bean>
</beans>
複製代碼

3.利用Spring容器建立託管對象Userspring

        ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
        User u = (User)context.getBean("User");
        System.out.println(u);

3、Bean的配置深刻

1.bean引用其餘beansql

實體類示例:數據庫

複製代碼
package test.Spring.helloworld;

public class HelloWorld {
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + ", user=" + user + "]";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;
    private User user;
    
    public HelloWorld(){
        
    }
    
    public HelloWorld(String name){
        this.name = name;
    }
}
複製代碼

配置示例:express

複製代碼
    <!-- reference other bean -->
    <bean id="HelloWorld" class="test.Spring.helloworld.HelloWorld">
        <!-- <property name="name" value="spring1"></property> -->
        <constructor-arg value="spring2" type="java.lang.String"></constructor-arg>
        <property name="user">
            <ref bean="User"/>
        </property>
    </bean>
複製代碼

調用方法依然是根據bean中的id緩存

2.集合bean配置session

實體類示例:app

複製代碼
package test.Spring.helloworld;

import java.util.List;
import java.util.Map;

public class User {
    public Map<String, Integer> getMap() {
        return map;
    }
    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", list=" + list
                + ", map=" + map + "]";
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private int id;
    private String name;
    private List<String> list;
    private Map<String,Integer> map;
    
}
複製代碼

配置示例:ide

複製代碼
    <!-- Configure the list bean -->
    <bean id="testList" class="test.Spring.helloworld.User">
        <property name="list">
            <list>
                <value>list1</value>
                <value>list2</value>
                <value>list3</value>
            </list>
        </property>
    </bean>
    
    <!-- configure the map -->
    <bean id="testMap" class="test.Spring.helloworld.User">
        <property name="map">
            <map>
                <entry key="first" value="1"></entry>
                <entry key="second" value="2"></entry>
                <entry key="third" value="3"></entry>
            </map>
        </property>
    </bean>
複製代碼

3.Properties類型的bean

實體類示例:

複製代碼
package test.Spring.helloworld;

import java.util.Properties;

public class DataSource {
    @Override
    public String toString() {
        return "Properties [properties=" + properties + "]";
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    private Properties properties;
    
}
複製代碼

配置示例:

複製代碼
    <!-- configure the properties -->
    <bean id="dataSource1" class="test.Spring.helloworld.DataSource">
        <property name="properties">
            <props>
                <prop key="user">root</prop>
                <prop key="password">1234</prop>
                <prop key="jdbcUrl">jdbc:mysql:///test</prop>
                <prop key="driverClass">com.mysql.jdbc.Driver</prop>
            </props>
        </property>
    </bean>
複製代碼

4.使用Util定義引用其餘bean的公共集合

須要先在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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util-4.0.xsd"
        xmlns:util="http://www.springframework.org/schema/util"    
        >    
</beans>
複製代碼

集合以及調用的xml配置

複製代碼
    <!-- if properties of collection are beans -->
    <util:list id="users">
        <ref bean="User"/>
        <ref bean="User"/>
        <ref bean="User"/>
    </util:list>
    
    <bean id="Users" class="test.Spring.helloworld.Users">
        <property name="list">
            <ref bean="users"/>
        </property>
    </bean>
複製代碼

5.使用p簡化bean的屬性賦值

首先,導入p的命名空間

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

實體類實例:

複製代碼
package test.Spring.helloworld;

import java.util.List;
import java.util.Map;

public class User {
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + "]";
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private int id;
    private String name;
    
}
複製代碼

配置示例:

    <!-- use p to write the bean quickly and conveniently -->
    <bean id="User1" class="test.Spring.helloworld.User" p:id="2" p:name="jayjay2" />

6.abstract模板bean

設置abstract=true代表此bean是模板bean,爲其餘bean提供屬性值模板

    <!-- template bean -->
    <bean abstract="true"  id="template" p:id="50" p:name="fromTemplate"></bean>
    <bean id="User2" parent="template" class="test.Spring.helloworld.User"></bean>

7.單例bean和原型bean

    <!-- use scope to build singleton/prototype bean -->
    <bean id="User3" parent="template" scope="singleton" class="test.Spring.helloworld.User"></bean>
    <bean id="User4" parent="template" scope="prototype" class="test.Spring.helloworld.User"></bean>

singleton:此bean爲單例,在context建立時已經建立,而且只有一個實例。

prototype:當須要時建立實例。

8.靜態工廠方法配置bean

靜態工廠類示例:

複製代碼
package test.Spring.FactoryBean;

import java.util.HashMap;
import java.util.Map;

public class StaticFactoryMethod {
    public static Map<String,Person> map = new HashMap<String,Person>();
    
    static {
        map.put("first", new Person(1,"jayjay1"));
        map.put("second", new Person(2,"jayjay2"));
    }
    
    public static Person getPerson(String key){
        return map.get(key);
    }
}
複製代碼

配置示例:

    <!-- static factory method -->    
    <bean id="person" factory-method="getPerson" class="test.Spring.FactoryBean.StaticFactoryMethod">
        <constructor-arg value="first" type="java.lang.String"></constructor-arg>
    </bean>

9.實例工廠方法配置bean

工廠類示例:

複製代碼
package test.Spring.FactoryBean;

import java.util.HashMap;
import java.util.Map;

public class InstanceFactoryMethod {
    public static Map<String,Person> map = new HashMap<String,Person>();
    
    static {
        map.put("first", new Person(1,"jayjay1"));
        map.put("second", new Person(2,"jayjay2"));
    }
    
    public Person getPerson(String key){
        return map.get(key);
    }
}
複製代碼

配置示例:

    <!-- instance factory method -->
    <bean id="InstanceFactoryMethod" class="test.Spring.FactoryBean.InstanceFactoryMethod"></bean>
    <bean id="person1" factory-bean="InstanceFactoryMethod" factory-method="getPerson">
        <constructor-arg value="second"></constructor-arg>
    </bean>

10.經過實現FactoryBean完成bean的配置

須要對FactoryBean接口的3個方法進行適當重寫

PersonFactoryBean類示例:

複製代碼
package test.Spring.FactoryBean;

import org.springframework.beans.factory.FactoryBean;

public class PersonFactoryBean implements FactoryBean<Person>{
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private int id;
    private String name;
    
    @Override
    public Person getObject() throws Exception {
        // TODO Auto-generated method stub
        return new Person(id,name);
    }

    @Override
    public Class<?> getObjectType() {
        // TODO Auto-generated method stub
        return Person.class;
    }

    @Override
    public boolean isSingleton() {
        // TODO Auto-generated method stub
        return false;
    }


}
複製代碼

配置示例:

    <!-- use factory bean to get a instance -->
    <bean id="person2" class="test.Spring.FactoryBean.PersonFactoryBean">
        <property name="id" value="3"></property>
        <property name="name" value="FactoryBean"></property>
    </bean>

4、經過註解配置bean

加上註解的類會被Spring容器管理

@Component

    標註於通用實體類

@Controller

    標註於Controller/Action

@Service

    標註於Service

@Respository

    標註於RespositoryImpl/DaoImlp

@Autowired

    依據類型自動裝配

@Qualifier

    指定自動裝載的bean的name

1.在Spring配置文件中導入context命名空間,並加入

<context:component-scan base-package="test.Spring.Annotation"></context:component-scan>

表示Spring將掃描test.Spring.Annotation及其子包中全部java文件,並將帶有註解的類加入Spring容器進行管理。

例如:

複製代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd" 
        xmlns:context="http://www.springframework.org/schema/context">
        <context:component-scan base-package="test.Spring.Annotation"></context:component-scan>
</beans>
複製代碼

2.模擬三層,並用Spring註解方式注入

項目結構:

Person實體類

複製代碼
package test.Spring.Annotation;
import org.springframework.stereotype.Component;

@Component
public class Person {
    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + "]";
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    private int id;    
    private String name;
}
複製代碼

PersonController

複製代碼
package test.Spring.Annotation.Controller;

import org.springframework.stereotype.Controller;

@Controller
public class PersonController {
    public void excute(){
        System.out.println("PersonController.excute()...");
    }
}
複製代碼

PersonService

複製代碼
package test.Spring.Annotation.Service;

import org.springframework.stereotype.Service;

@Service
public class PersonService {
    public void add(){
        System.out.println("PersonService.add()...");
    }
}
複製代碼

PersonRepository接口

package test.Spring.Annotation.Repository;

public interface PersonRepository {
    void add();
}

PersonRepositoryImpl接口實現類

複製代碼
package test.Spring.Annotation.Repository;

import org.springframework.stereotype.Repository;

@Repository
public class PersonRepositoryImpl implements PersonRepository {

    @Override
    public void add() {
        System.out.println("PersonRepositoryImpl.add()...");    
    }

}
複製代碼

Main類中測試

複製代碼
package test.Spring.Annotation;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.Spring.Annotation.Controller.PersonController;
import test.Spring.Annotation.Repository.PersonRepository;
import test.Spring.Annotation.Service.PersonService;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context =new ClassPathXmlApplicationContext("applicationContextForAnnotation.xml");
        
        //inject the common bean
        System.out.println(context.getBean("testAutowired"));
        
        //inject the repository
        PersonRepository pr = (PersonRepository)context.getBean("personRepositoryImpl");
        pr.add();
        
        //inject the controller
        PersonController pc = (PersonController)context.getBean("personController");
        pc.excute();
        
        //inject the service
        PersonService ps = (PersonService)context.getBean("personService");
        ps.add();
        
        
    }
}
複製代碼

3.泛型三層的注入

Spring配置文件

複製代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        " 
        xmlns:context="http://www.springframework.org/schema/context"    
        >
    <context:component-scan base-package="test.Spring.Generic.di"></context:component-scan>
</beans>
複製代碼

BaseRespository

複製代碼
package test.Spring.Generic.di;

public class BaseRepository<T> {
    
    public void save() {
        System.out.println("repository.save()...");
    }
}
複製代碼

PersonRepository

package test.Spring.Generic.di;

public interface PersonRespository {
    void save();
}

PersonRepositoryImpl

繼承BaseRepository就不須要再寫一次save方法,且同時實現了PersonRepository接口

複製代碼
package test.Spring.Generic.di;

import org.springframework.stereotype.Repository;

import test.Spring.Annotation.Person;

@Repository
public class PersonRespositoryImpl extends BaseRepository<Person> implements PersonRespository {

}
複製代碼

BaseService對Dao進行自動裝配,子類繼承後裝配的是子類Respository

複製代碼
package test.Spring.Generic.di;

import org.springframework.beans.factory.annotation.Autowired;

public class BaseService<T> {
    
    @Autowired
    protected BaseRepository<T> baseRespository;
    
    public void save(){
        System.out.println("service.save()...");
        System.out.println(baseRespository);
    }
}
複製代碼

PersonService繼承了BaseService,就不須要再寫實現save方法,定義Repository字段了

複製代碼
package test.Spring.Generic.di;

import org.springframework.stereotype.Service;

import test.Spring.Annotation.Person;

@Service
public class PersonService extends BaseService<Person>{
    
}
複製代碼

Main類中調用

複製代碼
package test.Spring.Generic.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context =new ClassPathXmlApplicationContext("applicationContextForGeneric.xml");
        PersonService ps = (PersonService)context.getBean("personService");
        ps.save();
    }
}
複製代碼

輸出爲

第二句說明調用的是繼承BaseService的PersonService拿到的Respository是PersonRepositoryImpl,說明泛型注入成功。    

 

 10、使用SpringAOP完成簡單的程序

1.導入SpringAOP所需jar包

2.編寫spring的配置文件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"
    
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util-4.0.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
        "
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"    
        >
    <!-- configure the package for spring to scan -->
    <context:component-scan base-package="test.Spring.AOP" />
    
    <!-- make the aspectj annotation to be used -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
複製代碼

3.建立一個HelloWord接口以及它的實現類HelloWordImpl

public interface HelloWord {
    public int sayHello(int num);
}
複製代碼
@Component
public class HelloWordImpl implements HelloWord{
    public int sayHello(int num){
        System.out.println("hello word");
        return 100/num;
    }
}
複製代碼

4.SpringAOP註釋的類型有5種

@Before 前置通知 在方法執行前執行

@After 後置通知 在方法執行後執行

@AfterThrowing 異常通知 在方法拋出異常以後執行

@AfterReturning 返回通知 在方法返回結果以後執行

@Around 環繞通知 環繞着方法執行

5.建立一個切面類(包含@Before @After @AfterThrowing @AfterReturning)

複製代碼
@Component
@Aspect
public class HelloWordAspect {
    
    @Before(value="execution(* test.Spring.AOP.HelloWord.sayHello(..))")
    public void beforeMethod(JoinPoint jp){
        String methodName = jp.getSignature().getName();
        System.out.println(methodName);
        System.out.println("before method execute,args are "+Arrays.toString(jp.getArgs()));
    }

    @After("execution(* test.Spring.AOP.HelloWord.sayHello(..))")
    public void afterMethod(JoinPoint jp){
        System.out.println("after method execute,args are "+Arrays.toString(jp.getArgs()));
    }
    
    @AfterThrowing(value="execution(* test.Spring.AOP.HelloWord.sayHello(..))",throwing="ex")
    public void afterThrow(Exception ex){
        System.out.println("afterThrow"+ex.getMessage());    
    }
    
    @AfterReturning(value="execution(* test.Spring.AOP.HelloWord.sayHello(..))",returning="result")
    public void afterReturn(Object result){
        System.out.println("the result is "+result);
    }
}
複製代碼

6.在主函數調用

複製代碼
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextForAOP.xml");
        
        HelloWord hw = (HelloWord) context.getBean("helloWordImpl");
        hw.sayHello(10);
    }
}
複製代碼

7.調用結果

結果說明,在sayHello方法是被Spring代理執行了,執行先後加上了一些切面類中定義的信息。

8.使用Around環繞通知切面類實現相似效果

 

複製代碼
@Component
@Aspect
public class HelloWordAspectAround {
    @Around(value="execution(* test.Spring.AOP.HelloWord.sayHello(..)))")
    public Object aroundMethod(ProceedingJoinPoint pjp){
        Object result = null;
        String methodName = pjp.getSignature().getName();
        try {
            result = pjp.proceed();        
            System.out.println("the result is "+result);
        } catch (Throwable e) {
            System.out.println("Exception occurs : "+e.getMessage());
            throw new RuntimeException(e);
        }
        System.out.println(methodName+" end");
        
        return result;
    }
}
複製代碼

 

11、SpringAOP整合Hibernate並使用事務(模擬買書的過程)

1.內容準備

①.編寫實體類

Book

複製代碼
public class Book {
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public int getCount() {
        return count;
    }
    public void setCount(int count) {
        this.count = count;
    }
    private int id;
    private String name;
    private int price;
    private int count;
}
複製代碼

Customer

複製代碼
public class Customer {
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getBalance() {
        return balance;
    }
    public void setBalance(int balance) {
        this.balance = balance;
    }
    private int id;
    private String name;
    private int balance;
}
複製代碼

②.編寫實體類映射文件

複製代碼
<hibernate-mapping package="springaop.model">
    <class name="Book" table="t_book">
        <id name="id" type="int" column="id" >
            <generator class="native"></generator>
        </id>
        <property name="name" type="string" column="name"/>
        <property name="price" type="int" column="price"/>
        <property name="count" type="int" column="count"/>

    </class>
</hibernate-mapping>
複製代碼
複製代碼
<hibernate-mapping package="springaop.model">
    <class name="Customer" table="t_customer">
        <id name="id" type="int" column="id" >
            <generator class="native"></generator>
        </id>
        <property name="name" type="string" column="name"/>
        <property name="balance" type="int" column="balance"/>

    </class>
</hibernate-mapping>
複製代碼

③.編寫dao及daoImpl

public interface ShopRepository {
    public int findBookPriceByBookName(String name);
    public void updateBookCount(String name);
    public void updateUserBalance(String name,int price);
}
複製代碼
@Repository
public class ShopRepositoryImpl implements ShopRepository{

    @Autowired
    private SessionFactory sessionFactory;
    
    private Session getSession(){
        return sessionFactory.getCurrentSession();
    }
    
    @Override
    public int findBookPriceByBookName(String name) {
        String sql = "select b.price from Book b where b.name=?";
        Query query = getSession().createQuery(sql).setString(0, name);
        return (Integer)query.uniqueResult();
    }

    @Override
    public void updateBookCount(String name) {
        String sql1 = "select b.count from Book b where b.name=?";
        Query query = getSession().createQuery(sql1).setString(0,name);
        int count = (int)query.uniqueResult();
        if(count<=0){
            throw new RuntimeException("庫存不足");
        }
        
        String sql2 = "update Book b set b.count=b.count-1 where b.name=?";
        getSession().createQuery(sql2).setString(0,name).executeUpdate();        
    }

    @Override
    public void updateUserBalance(String name, int price) {
        String sql1 = "select c.balance from Customer c where c.name=?";
        Query query = getSession().createQuery(sql1).setString(0,name);
        int count = (int)query.uniqueResult();
        if(count-price<0){
            throw new RuntimeException("餘額不足");
        }
        
        String sql2 = "update Customer c set c.balance=c.balance-? where c.name=?";
        getSession().createQuery(sql2).setInteger(0, price).setString(1,name).executeUpdate();    
    }

}
複製代碼

④.編寫service及serviceImpl

public interface ShopService {
    public void shop(String bookName,String username);
}
複製代碼
@Service
public class ShopServiceImpl implements ShopService{

    @Autowired
    private ShopRepository sr;
    
    @Override
    public void shop(String bookName, String username) {
        int price = sr.findBookPriceByBookName(bookName);
        sr.updateUserBalance(username, price);
        sr.updateBookCount(bookName);
    }

}
複製代碼

2.加入Hibernate

①.添加hibernate必須的jar包

 

②.添加hibernate.cfg.xml

複製代碼
<hibernate-configuration>
    <session-factory>
        <!-- 配置hibernate的基本屬性 -->    
        <!-- 1.數據源的配置,配置到SpringIOC中,此處不須要再進行配置 -->
        <!-- 2.關聯實體的映射文件 .hbm.xml文件也在IOC容器配置SessionFactory實例時配置 -->
        <!-- 3.配置hibernate的基本屬性  方言、sql顯示及格式化、數據庫表生成策略、二級緩存-->        
        <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        
        <!-- 配置hibernate二級緩存相關 -->
        
    </session-factory>
</hibernate-configuration>
複製代碼

 

3.加入Spring

①.導入Spring必須的jar包

②.配置Spring的applicationContext.xml及db.properties文件

複製代碼
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd 
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util-4.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd             
        "
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"    
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        >

    <!-- 配置Spring掃描的包 -->
    <context:component-scan base-package="springaop"></context:component-scan>

    <!-- 配置數據源 -->
    <!-- 導入資源文件 -->
    <context:property-placeholder location="classpath:db.properties"/>
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>
    
    <!-- 配置Hibernete的SessionFactory實例 -->
    <!-- 經過配置Spring提供的LcalSessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
        <property name="mappingLocations" value="classpath:springaop/model/*.hbm.xml"></property>
    </bean>
    
    <!-- 配置Spring的聲明式事務 -->
    <!-- 1.配置事務管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
    
    <!-- 2.配置事務屬性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    
    <!-- 3.配置事務切點,並把切點和事務關聯起來, -->
    <aop:config>
        <aop:pointcut expression="execution(* springaop.service.*.*(..))" id="txPointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>
    
</beans>
複製代碼
複製代碼
jdbc.user=root
jdbc.password=1234
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///test

jdbc.initialPoolSize=5
jdbc.maxPoolSize=10
複製代碼

4.運行測試

複製代碼
public class test {
    private ApplicationContext context = null;
    
    private ShopService ss = null;

    {
        context = new ClassPathXmlApplicationContext("applicationContext.xml");
        ss= context.getBean(ShopService.class);
    }
    
    
    @Test
    public void test() throws SQLException{
        DataSource ds = context.getBean(DataSource.class);
        System.out.println(ds.getConnection());
    }
    
    @Test
    public void test1(){
        ss.shop("Java", "jayjay");
    }
    
    @Test
    public void test3(){
        ss.shop("C", "jayjay");
    }
}
複製代碼

當錢不夠的時候,會拋出異常「餘額不足」,而且事務回滾;當錢足夠時,正常執行。

相關文章
相關標籤/搜索