Spring

一. 环境搭建(简单三步就能创建一个Spring框架)

  1. 创建一个动态web项目
  2. 将Spring开发包引入项目(包下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring/)
  3. 将Spring配置文件beans.xml拷贝到src下面(内容如下)
    <?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">
    </beans>
    

二. 利用Spring管理对象实例(下面用实际代码说明Spring怎样管理对象)

  1. 在beans.xml中添加需要管理的对象(添加在<bean>中)
      <bean class="com.yuanhuan.helloworld.HelloWorld" id="helloWorld"/>  <!--id为对象名-->
    
  2. 使用(在java代码中调用实例)
     ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
     HelloWorld helloWorld = (HelloWorld) ac.getBean("helloWorld");
        
    

三. 简单理解Spring IOC(下面一个简单例子来说明对IOC的理解)

  1. 含义:IOC(控制反转:Inverse ofControl ),又称作 依赖注入,是一种重要的面向对象编程的法则来削减计算机程 序的耦合问题,也是轻量级的 Spring 框架的核心

  2. 举例:若主管每次要安排不同员工做测试,每个员工和主管都是一个类,所以每次都需要该大量的源代码,维护极其不方便,所以就可以用控制反转的方式(或者说依赖注入),通过Spring来管理对象实例,每次更改只需要修改配置文件(beans.xml)即可。
    代码:

    //lisi.java
    public class LiSi implements Worker {
        @Override
        public void test() {
            System.out.println("李四正在做测试");
        }
    }
    //zhangsan.java
    public class ZhangSan implements Worker {
        @Override
        public void test() {
            System.out.println("张三正在做测试");
    
        }
    }
    //worker.java
    public interface Worker {
        void test();
    }
    //zhuguan.java
    public class ZhuGuan {
        Worker worker;
    
        public void setWorker(Worker worker) {
            this.worker = worker;
        }
    
        public void doTest() {
            worker.test();
        }
    
    }
    //test.java
    public class Test {
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
            ZhuGuan zhuGuan = (ZhuGuan) ac.getBean("zhuGuan");
            zhuGuan.doTest();
    
        }
    }
    //beans.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">
    	<bean class="com.yuanhuan.service.LiSi" id="liSi"/>
    	<bean class="com.yuanhuan.service.ZhangSan" id="zhangSan"/>
    	<bean class="com.yuanhuan.service.ZhuGuan" id="zhuGuan">
    	<property name="worker" ref="liSi"/><!--意思是将liSi对象赋值给zhuGuan对象中的worker属性(worker对象必须要有set方法)-->
    	</bean>
    </beans>
    

注:需要张三做测试的时候,只需要在beans.xml中的把liSi换为zhangSan即可。

四. 依赖注入(下面内容都是说String通过beans.xml怎样来注入属性,构造方法等。都是一些具体写法,实际内容不多)

1. 属性注入;

   <!--属性注入-->
    <bean class="com.yuanhuan.service.People" id="people">
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
    </bean>

2. 构造函数注入;(通过类型;通过索引;联合使用)

    <!--构造方法注入(通过类型)-->
    <bean class="com.yuanhuan.service.People" id="people2">
        <constructor-arg type="java.lang.String" value="李四"/>
        <constructor-arg type="int" value="22"/>
    </bean>
    <!--构造方法注入(通过索引)-->
    <bean class="com.yuanhuan.service.People" id="people3">
        <constructor-arg index="0" value="王五"/>
        <constructor-arg index="1" value="25"/>
    </bean>
    <!--构造方法注入(默认按顺序)也可使用联合注入(结合类型和索引)-->
    <bean class="com.yuanhuan.service.People" id="people4">
        <constructor-arg  value="王六"/>
        <constructor-arg  value="26"/>
    </bean>

3. 工厂方法注入;(非静态工厂,静态工厂)

<!--非静态工厂方法注入(通过方法制造对象)-->
<bean id="peopleFactory" class="com.yuanhuan.service.PeopleFactory"/>
<bean id="people6" factory-bean="peopleFactory" factory-method="createPeople"/>
<!--静态工厂方法注入-->
<bean id="people7" class="com.yuanhuan.service.PeopleFactory" factory-method="createStaticPeople"/>

4. 泛型依赖注入;(Spring4 整合 Hibernate4 的时候顺带讲)

5. 参数注入

  1. 基本类型值;
  2. 注入 bean;
  3. 内部 bean;
  4. null 值;
  5. 级联属性;
  6. 集合类型属性;

beans.xml <beans><beans>中代码如下:

    <!--基本类型值注入-->
    <bean class="com.yuanhuan.service.People" id="people">
        <property name="name" value="张三"/>
        <property name="age" value="21"/>
    </bean>
    <!--注入bean-->
    <bean id="dog1" class="com.yuanhuan.service.Dog">
        <property name="name" value="Jack"/>
    </bean>
    <bean id="people8" class="com.yuanhuan.service.People">
        <property name="name" value="张三"/>
        <property name="age" value="15"/>
        <property name="dog" ref="dog1"/>
    </bean>
    <!--内部注入bean-->
    <bean id="people9" class="com.yuanhuan.service.People">
        <property name="name" value="张三"/>
        <property name="age" value="15"/>
        <property name="dog">
            <bean  class="com.yuanhuan.service.Dog">
                <property name="name" value="jac内部"/>
            </bean>
        </property>
    </bean>
    <!--注入null-->
    <bean id="people10" class="com.yuanhuan.service.People">
        <property name="name" value="张三"/>
        <property name="age" value="15"/>
        <property name="dog">
            <null></null>
        </property>
    </bean>
    <!--注入级联属性-->
    <bean id="people11" class="com.yuanhuan.service.People">
        <property name="name" value="张三"/>
        <property name="age" value="15"/>
        <property name="dog.name" value="jack级联"/><!--注意:使用级联属性注入时,原People中dog属性必须初始化,否则会报空指针-->
    </bean>
    <!--注入集合-->
    <bean id="people12" class="com.yuanhuan.service.People">
        <property name="name" value="张三"/>
        <property name="age" value="15"/>
        <property name="dog" ref="dog1"/><!--dog1是注入bean(上面定义过的)-->
       <!--(List)-->
        <property name="hobbies">
            <list>
                <value>吃烧烤</value>
                <value>喝啤酒</value>
            </list>
        </property>
        <!--(Set)-->
        <property name="love">
            <set>
                <value>唱歌</value>
                <value>跳舞</value>
            </set>
        </property>
        <!--(Map)-->
        <property name="score">
            <map>
                <entry>
                    <key><value>语文</value></key>
                    <value>90</value>
                </entry>
                <entry>
                    <key><value>数学</value></key>
                    <value>100</value>
                </entry>
            </map>
        </property>
    </bean>

测试代码

ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
People people = (People) ac.getBean("beans.xml中对应id值");
System.out.println(people);

People代码:

package com.yuanhuan.service;


import java.util.*;

public class People {
    String name;
    int age;
    Dog dog=new Dog();
    public People() {
        super();
    }

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
    List<String> hobbies = new ArrayList<>();
    Set<String> Love = new TreeSet<>();
    Map<String, Integer> score = new HashMap<>();

    public List<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(List<String> hobbies) {
        this.hobbies = hobbies;
    }

    public Set<String> getLove() {
        return Love;
    }

    public void setLove(Set<String> love) {
        Love = love;
    }

    public Map<String, Integer> getScore() {
        return score;
    }

    public void setScore(Map<String, Integer> score) {
        this.score = score;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

   

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", dog=" + dog.getName() +
                ", hobbies=" + hobbies +
                ", Love=" + Love +
                ", score=" + score +
                '}';
    }
}

6.Spring 自动装配(自动装配机制慎用,它屏蔽了装配细节,容易产生潜在的错误)

通过配置 default-autowire 属性,Spring IOC 容器可以自动为程序注入 bean;默认是 no,不启用自动装配; default-autowire 的类型有 byName(根据bean名称),byType(根据bean类型),constructor(根据构造方法名称)

  1. 需要在beans.xml中加入default-autowirr属性

    <?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"
        **default-autowire="default"**>
    
  2. 具体实例

    1. 当default-autowire=“byName”:

        <!--根据名称自动注入bean-->
          <bean id="dog" class="com.yuanhuan.service.Dog">
              <property name="name" value="Jack"/>
          </bean>
          <bean id="people13" class="com.yuanhuan.service.People">
              <property name="name" value="王麻子"/>
              <property name="age" value="55"/>
              &lt;!&ndash;自动注入dog&ndash;&gt;
          </bean>
      
    2. 当default-autowire=“byType”:

      <!--根据类型自动注入-->
          <bean id="dog" class="com.yuanhuan.service.Dog">
              <property name="name" value="Jack"/>
          </bean>
          <bean id="people14" class="com.yuanhuan.service.People">
              <property name="name" value="王麻子"/>
              <property name="age" value="55"/>
              &lt;!&ndash;自动注入dog1(尽管People中没有dog1而是dog,但根据属性自动注入也能注入)&ndash;&gt;
          </bean>
      
    3. 当default-autowire=“constructor”:

       <!--根据构造方法注入(People类中必须有参数为Dog的构造方法)-->
          <bean id="dog" class="com.yuanhuan.service.Dog">
              <property name="name" value="Jack"/>
          </bean>
          <bean id="people14" class="com.yuanhuan.service.People">
              <property name="name" value="王麻子"/>
              <property name="age" value="55"/>
              <!--根据构造方法自动注入bean(dog)-->
          </bean>
      

7. 方法注入(用的比较少,了解)

Springbean 作用域默认是 单例 singleton(每个bean生成一个对象)意思就是通过bean注入,每次对象都为同一个对象;
配置步骤(以人类有属性狗类为例子):

  1. 将人类改为抽象类
  2. 将getDog改为抽象方法
  3. 在Dog bean中加一个scope=“prototype”
  4. 在People bean 中把dog property改为<lookup-method name=“getDog” bean=“dog”/>

8. 方法替换(用的比较少,了解)

利用bean可以实现一个对象执行另一个对象中的方法

五. bean直接的关系

  1. 继承;

  2. 依赖;

  3. 引用
    对应实例:

    <!--继承-->
    <bean id="abstractPeople" class="com.yuanhuan.service.People2" abstract="true">
        <property name="className" value="大三"/>
    </bean>
    <bean id="xiaoming" parent="abstractPeople">
        <property name="name" value="小明"/>
        <property name="age" value="15"/>
    </bean>
    <bean id="xiaofang" parent="abstractPeople">
        <property name="name" value="小芳"/>
        <property name="age" value="12"/>
    </bean>
    <!--依赖(假如小华依赖小芳),-->
    <bean id="xiaofang" parent="abstractPeople" depends-on="xiaofang"><!--当创建小华bean时,会先去创建小芳bean-->
        <property name="name" value="小芳"/>
        <property name="age" value="12"/>
    </bean>
    <!--引用(就是前面提到的<property name="dog1" ref="dog">,就是将dog bean 对象注入dog1中)-->

六. bean的作用范围

  1. singletonSpring ioc 容器中仅有一个 Bean 实例,Bean 以单例的方式存在;
  2. prototype 每次从容器中调用 Bean 时,都返回一个新的实例;
  3. request 每次 HTTP 请求都会创建一个新的 Bean;
  4. session 同一个 HTTPSession 共享一个 Bean;
  5. globalsession 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;
  6. application 同一个 Application 共享一个 Bean;

七. Spring AOP(面向切面编程,说的通俗易懂就是可以动态的,不修改源代码的情况下为程序添加功能,如在一个方法的前后添加一下功能)

AOP实例分类

  1. 前置通知;
  2. 后置通知;
  3. 环绕通知; (环绕通知相当于前后置通知的结合)
  4. 返回通知;
  5. 异常通知

例子(在 beans.xml中)

注意:在定义切点时 * 表示匹配任意方法或类或包,(…)表示方法参数为空或任意类型任意多少。
切面:表示动态添加功能的类
切点:表示在哪个类的哪个方法添加切面
首先在beans.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"
    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">
</beans>
    

具体例子:

    <bean id="studentManager" class="com.yuanhuan.service.StudentManagerImp"/>
    <bean id="studentAspect" class="com.yuanhuan.AOP.StudentAspect"/>
    <aop:config><!--切面配置-->
        <aop:aspect id="studentAspect" ref="studentAspect"><!--定义一个切面-->
            <aop:pointcut id="studentPoinCut" expression="execution(* com.yuanhuan.service.StudentManagerImp.add(..))"/><!--定义一个切点-->
         <!-前置通知-->
            <aop:before method="addStudentBefore" pointcut-ref="studentPoinCut"/><!--在切点前执行方法addStudentBefore-->
             <!-后置通知-->
            <aop:after method="addStudentAfter" pointcut-ref="studentPoinCut"/>
     	     <!-环绕通知-->
     	    <aop:around method="doAround" pointcut-ref="studentPoinCut"/>
     	    <!-异常通知-->
     	    <aop:after-throwing method="doAfterThrowing" pointcut-ref="studentPoinCut" throwing="throwable"/>

        </aop:aspect>
    </aop:config>
//StudentAspect.java(切面类)
public class StudentAspect {
	//前置通知
    public void addStudentBefore(JoinPoint jp) {
    	//JoinPoint中封装了很多方法,下面三个依次为获取类、方法名、参数(参数时一个数组,下面[0]就是表示第一个参数)
    	System.out.println(jp.getTarget().getClass());
        System.out.println(jp.getSignature().getName());
        System.out.println(jp.getArgs()[0]);
        System.out.println("准备添加学生");
    }
    //后置通知
    public void addStudentAfter(JoinPoint jp){
        System.out.println("添加学生完成");
    }
    //环绕通知 
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("准备添加学生【环绕通知】");
        pjp.proceed();//将切点方法转换到这里执行,这个会返回一个值,就为原切点方法返回的值
        System.out.println("添加学生完成【环绕通知】");
    }
        //异常通知
    public void doAfterThrowing(JoinPoint jp,Throwable throwable) {
        System.out.println(throwable.getMessage());
        System.out.println("异常通知");
    }
}

八. 对jdbc的支持(方便数据库的操作)

1.配置:引入包

Spring包:
在这里插入图片描述
jdbc包:
在这里插入图片描述
dbcp包:
在这里插入图片描述

2.修改beans.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:context="http://www.springframework.org/schema/context"
    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">
    <!--数据源(class为apache的数据库连接池)-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--加载指定路径的配置文件-->
    <context:property-placeholder location="jdbc.properties"/>
    <!--定义jdbcTemplate  bean,注入数据源-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--将jdbcTemplate注入需要使用的类中-->
    <bean id="studentDao" class="com.yuanhuan.dao.impl.StudentDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"/>
    </bean>

    <bean id="studentService" class="com.yuanhuan.service.impl.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"/>
    </bean>
    
</beans>

3.具体使用

public class StudentDaoImpl implements StudentDao {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public int addStudent(Student student) {
        //只需要写核心业务,其他异常,连接什么的都封装好了
        String sql = "insert into User values(null,?,?)";
        Object[] params = new Object[]{student.getName(), student.getAge()};
        return jdbcTemplate.update(sql,params);
    }
    @Override
    public int updateStudent(Student student) {
        String sql = "update User set name=?,age=? where id=?";
        Object[] params = new Object[]{student.getName(), student.getAge(), student.getId()};
        return jdbcTemplate.update(sql,params);
    }
    @Override
    public int deleteStudent(Student student) {
        String sql = "delete from User where id=?";
        Object[] params = new Object[]{student.getId()};
        return jdbcTemplate.update(sql,params);
    }
    @Override
    public List<Student> findStudents() {
        String sql="select * from User";
        List<Student> students = new ArrayList<>();
        jdbcTemplate.query(sql, new RowCallbackHandler() {
            @Override
            public void processRow(ResultSet rs) throws SQLException {
                students.add(new Student(rs.getInt("id"), rs.getString("name"), rs.getInt("age")));
            }
        });
        return students;
    }
}

4.jdbcSupport(可以简化一点jdbcTemplate的配置)

在需要使用jdbcTemplate的类中继承JdbcDaoSupport ,beans.xml中就不用配置jdbcTemplate,只需要向需要使用jdbcTemplate的类的bean中直接注入数据源(property name=dataSource),使用时直接this.getJdbcTemplate()就可以了。

5.NamedParameterJdbcTemplate(支持命名参数,就是在写sql语句时,参数更加直观)

九. 对事务的支持

例如银行转账,A转账给B,若A转账后出现异常,此时B未收到钱,此时需要恢复A转账之前的状态。这个就时事务的原子性(一个事务要么不执行,要么全部执行)

1. 事务简介(需满足下面条件之一)

  1. 原子性;
  2. 一致性;
  3. 隔离性;
  4. 持久性

2. 编程式事务管理(缺点:代码入侵事务本身代码,导致代码乱)

  1. 需要使用事务管理器(transactionTemplate)类中:
public class TransactionService {
    private TransactionTemplate transactionTemplate;

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    public  void  doTransactionTest(){
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus transactionStatus) {
                //在这个方法中执行的语句就是一个事务
                System.out.println("执行一个事务");
            }
        });
    }
}
  1. beans.xml中
	<!--数据源(class为apache的数据库连接池)-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--jdbc事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--添加transactionTemplate bean-->
    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"/>
    </bean>
    <!--在需要使用transactionTemplate中注入transactionTemplate  bean-->
    <bean id="transactionService" class="com.yuanhuan.service.TransactionService">
        <property name="transactionTemplate" ref="transactionTemplate"/>
    </bean>
  1. test:
public class TransactionTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        TransactionService transactionService = (TransactionService) applicationContext.getBean("transactionService");
        transactionService.doTransactionTest();
    }
}

3.声明式事务管理: (通过事务切面)

1. 使用xml 配置声明式事务:在beans.xml中几行搞定,比较常用。

  1. 修改beans.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:context="http://www.springframework.org/schema/context"
    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/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
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>

  1. 添加事务通知
    <!--数据源(class为apache的数据库连接池)-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--jdbc事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!--对所有方法 -->
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <!--配置事务切面-->
    <aop:config>
        <!--配置切点-->
        <aop:pointcut id="serviceMethod" expression="execution(* com.yuanhuan.service.*.*(..))"/>
        <!--配置事务通知,对切点进行事务管理,也就是切点都为一个事务-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
    </aop:config>

2. 使用注解配置声明式事务,就是在方法上面加@XXX,虽简单,但是对于大项目,积少成多。)

  1. 在beans.xml中
    <!--数据源(class为apache的数据库连接池)-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--jdbc事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>

  1. 在需要进行事务管理的类或方法前面加: @Transactional

4.事务传播(某个service类需要调用另一个service类,且因为每个service方法都有事务,这是后就有事务的嵌套,从而产生了事务的传播行为)

  1. 种类(在<tx:method name="*"/>中添加propagation=? 来配置,?号值为下面六种,一般只用第一种):
    1. REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
    2. SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
    3. MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
    4. REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
    5. NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    6. NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。

十.自动添加bean

在beans.xml中可以配置一下,然后在每个类前加@XXX,Spring就会自动为其添加bean(类中属性类也可以添加@XXX(xxx需要与本身类相同),自动注入bean)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值