• Java


    一. IOC 和 DI

    IOC : 控制反转,将对象的创建权反转给了 Spring。
    DI  : 依赖注入,前提是必须要有 IOC 的环境,Spring 管理这个类的时候将类的依赖的属性注入(设置)进来。


    二. 工厂类

    //  1. 加载类路径
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserDao userDao = (UserDao) applicationContext.getBean("userDao");
    userDao.save();
    
    // 2. 加载磁盘中的 文件路径
    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("C:/Users/Administrator/Desktop/applicationContext.xml");
    UserDao userDao = (UserDao) applicationContext.getBean("userDao");
    userDao.save();




    三. Bean 的作用范围配置 (xml 文件中)

    1. scope : Bean 的作用范围。
    !    - singleton     : 默认,Spring 会采用单例模式创建这个对象。
    !    - prototype     : 多例模式。(Struts2 和 Spring 整合时会用到)
        - request       : 应用在 Web 项目中,Spring 创建这个类以后,将这个类存入到 request 范围中。
        - session       : 应用在 Web 项目中,Spring 创建这个类以后,将这个类存入到 session 范围中。
        - globalsession : 应用在 Web 项目中,必须在 porlet 环境下使用,如果没有这个环境,相对于 session。



    四. Spring 的属性注入方式(xml)

    1. 构造方法
    // 构造方法 (需要提供构造器)

    <!--  1. 构造方法  -->
    <bean id="shop" class="com.q.spring.demo2.ShopDao">
        <constructor-arg name="name" value="apple" />
        <constructor-arg name="price" value="100" />
    </bean>
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        ShopDao shopDao = (ShopDao) applicationContext.getBean("shop");
        System.out.println(shopDao);
    
    }



    2. set 方式的属性注入

    <!--  2. set 方法  -->
    <bean id="shop2" class="com.q.spring.demo2.ShopDao2">
        <property name="name" value="pear" />
        <property name="price" value="22" />
    </bean>
    
    <!--  2. set 方法 (p名称空间属性注入) -->
    <bean id="shop2" class="com.q.spring.demo2.ShopDao2" p:name="q" p:price="2222"></bean>
    
    
    <!--  2. set 方法 (SpEL 属性注入) -->
    <bean id="shop2" class="com.q.spring.demo2.ShopDao2">
        <property name="name" value="#{'q1'}"></property>
        <property name="price" value="#{111}"></property>
    </bean>
    // set 方式的属性注入(需要提供 set 方法)
    @Test
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        ShopDao2 shopDao = (ShopDao2) applicationContext.getBean("shop2");
        System.out.println(shopDao);
    
    }



    3. set 方法注入对象类型 (属性中依赖类)

    <!--  3. set 方法注入对象类型的属性  -->
    <bean id="person" class="com.q.spring.demo2.Person">
        <property name="name" value="q" />
        <property name="shopDao2" ref="shop2" />
    </bean>
    
    
    <!--  3. set 方法注入对象类型的属性 (p名称空间属性注入) -->
    <bean id="person" class="com.q.spring.demo2.Person" p:name="q1" p:shopDao2-ref="shop2"></bean>
    
    
    <!--  3. set 方法注入对象类型的属性 (SpEL 属性注入) -->
    <bean id="person" class="com.q.spring.demo2.Person">
        <property name="name" value="#{'q1'}"></property>
        <property name="shopDao2" value="#{shop2}"></property>
    </bean>
    // set 方法注入对象类型(需要提供 set 方法)
    @Test
    public void demo3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    
    }




    4. p名称空间属性注入

    <bean id="person" class="com.q.spring.demo2.Person" p:name="q1" p:shopDao2-ref="shop2"></bean>



    5. SpEL 属性注入 (Spring 3.0 之后)

    <bean id="shop2" class="com.q.spring.demo2.ShopDao2">
        <property name="name" value="#{'q1'}"></property>
        <property name="price" value="#{111}"></property>
    </bean>




    6. 集合类型的注入 ( arrs list set map )

    private String[] arrs;
    private List<String> list;
    private Set<String> set;
    private Map<String, String> map;
    <bean id="typealls" class="com.q.spring.demo2.typeAlls">
        <!--  数组类型  -->
        <property name="arrs">
            <list>
                <value>a</value>
                <value>b</value>
                <value>c</value>
            </list>
        </property>
    
        <!--  list集合  -->
        <property name="list">
            <list>
                <value>a1</value>
                <value>b1</value>
                <value>c1</value>
            </list>
        </property>
    
        <!--  set集合  -->
        <property name="set">
            <set>
                <value>a1</value>
                <value>b1</value>
                <value>c1</value>
            </set>
        </property>
    
        <!--  map 集合  -->
        <property name="map">
            <map>
                <entry key="b2" value="b2" />
                <entry key="b2" value="b2" />
                <entry key="b2" value="b2" />
            </map>
        </property>
    
    </bean>




    五. 分模块开发的配置

    1. 直接在一个xml文件中导入

    <import resource="applicationContext.xml" />   


    2. 在创建 ClassPathXmlApplicationContext 时可传多个参数路径

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml1","applicationContext.xml2");



    六. Spring 的 IOC 注解开发

    1. 引入约束: 使用注解开发引入 Context 约束

    <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" 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">
    </beans>



    2. 开启 Spring 的组件扫描

    <!--  配置组件扫描(哪些包下的类使用IOC注解)  -->
    <context:component-scan base-package="包路径"></context:component-scan>



    3. 在类上添加注解

    - @Component : 组件
        - 装饰一个类,将这个类交给 Spring 管理。    

        - 这个注解有三个衍生注解:        - @Controller : web 层
            - @Service       : service 层
            - @Repository : dao 层

    import org.springframework.stereotype.Component;
    
    // value 可省略: @Component("shopDao")
    @Component(value = "userDao")  // 相当于在 <bean id="userDao" class="com.q.spring.demo2.userDemo2" />
    public class userDemo2 implements UserDao {
        public void save(){
            
        }
    }


    4. 注解方式设置属性值

    注解方式:使用注解方式,可以没有 set 方法。

        - 属性如果有 set 方法,需要将属性注入的注解加到 set 方法上。

    // 如:
    @Value("添加注解")
    public void setName(String name){
        this.name = name;
    }


       - 属性如果没有 set 方法,需要将属性注入的注解添加到属性上。

    // 如:
    @Value("添加注解")
    private String name;




    5. 属性注入的注解

    # 普通属性:
        @Value     : 设置普通属性的值
    # 对象类型属性:
        @Autowired : 设置对象类型的属性值。但是按照类型完成属性注入(按照类名的一致)。
            - 可以通过 @Qualifier 和 @Autowired 配合使用来修改为按照名称属性注入。
            
        @Resource  : 完成对象类型的属性注入,按照名称完成属性注入。 (常用)。



    6. Bean 的其他注解

    # 生命周期相关注解:
        @PostConstruct   : 初始化方法
        @PreDestroy         : 销毁方法

    # Bean 作用范围的注解:
        @scope    : 作用范围
        参数:
            - singleton : 默认单例
            - prototype : 多例




    七. Spring 的 AOP 的 XML 开发
     
    1. applocationContext.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">
    
        <!--  配置目标对象 :被增强的对象 -->
        <bean id="productDao" class="com.q.spring.demo1.ProductDaoImpl" />
    
        <!--  将切面类交给 Spring 管理  -->
        <bean id="myAspect" class="com.q.spring.demo1.MyAspectXml" />
    
        <aop:config>
            <!--  通过AOP的配置完成对目标类产生代理  -->
            <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.save(..))" id="pointcut1" />
            <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.delete(..))" id="pointcut2" />
            <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.update(..))" id="pointcut3" />
            <aop:pointcut expression="execution(* com.q.spring.demo1.ProductDaoImpl.find(..))" id="pointcut4" />
    
            <!--  配置切面  -->
            <aop:aspect ref="myAspect">
                <!--  前置通知:获得切入点信息  -->
                <aop:before method="checkPri" pointcut-ref="pointcut1" />
                
                <!--  后置通知  -->
                <aop:after-returning method="writeLog" pointcut-ref="pointcut2" returning="result" />
    
                <!--  环绕通知  -->
                <aop:around method="around" pointcut-ref="pointcut3" />
    
                <!--  异常抛出通知  -->
                <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ex" />
    
                <!--  最终通知  -->
                <aop:after method="after" pointcut-ref="pointcut4" />
            </aop:aspect>
        </aop:config>
    </beans>

     

    2. ProductDao.java  接口文件

    package com.q.spring.demo1;
    
    public interface ProductDao {
        public void save();
        public void update();
        public String delete();
        public void find();
    }



    3. ProductDaoImpl.java  DAO文件

    package com.q.spring.demo1;
    
    public class ProductDaoImpl implements ProductDao {
    
        @Override
        public void save() {
            System.out.println("save");
        }
    
        @Override
        public void update() {
            System.out.println("update");
        }
    
        @Override
        public String delete() {
            System.out.println("delete");
            return "Delete!!!";
        }
    
        @Override
        public void find() {
            System.out.println("find");
    //        int i = 1/0;
        }
    }

     

    4. MyAspectXML.java

    package com.q.spring.demo1;
    
    // 切面类
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class MyAspectXml {
    
        // 前置通知
        public void checkPri(JoinPoint joinpoint){
            System.out.println("权限校验 "+ joinpoint);
        }
    
        // 后置通知
        public void writeLog(Object result){
            System.out.println("日志记录 "+ result);
        }
    
        // 环绕通知 : 性能监控
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
            System.out.println("环绕前通知...");
            Object obj = joinPoint.proceed();
            System.out.println("环绕后通知...");
            return obj;
        }
    
        // 异常抛出通知
        public void afterThrowing(Throwable ex){
            System.out.println("异常抛出通知..."+ ex.getMessage());
        }
    
        // 最终通知:类似于 finally
        public void after(){
            System.out.println("最终通知...");
        }
    }



    5. 测试文件

    package com.q.spring.demo1;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SpringDemo1 {
    
        @Resource(name="productDao")
        private ProductDao productDao;
    
        @Test
        public void demo1(){
            productDao.save();
            productDao.update();
            productDao.delete();
            productDao.find();
        }
    }



    八. Srping 的 AOP 注解

    1. applocationContext.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: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/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">
    
            <!--  在配置文件中开启注解的AOP开发  -->
            <aop:aspectj-autoproxy />
    
            <!--  配置目标类  -->
            <bean id="orderDao" class="com.q.spring.demo1.OrderDao" />
    
            <!--  配置切面类  -->
            <bean id="myAspect" class="com.q.spring.demo1.MyAspectAnno" />
    </beans>


    2. OrderDao.java 文件

    package com.q.spring.demo1;
    
    public class OrderDao {
        public void save(){
            System.out.println("save...");
        }
    
        public void update(){
            System.out.println("update...");
        }
    
        public String delete(){
            System.out.println("delete...");
            return "Delete!!!";
        }
    
        public void find(){
            System.out.println("find...");
    //        int i = 1/0;
        }
    }




    3. MyAspectAnno.java 文件

    package com.q.spring.demo1;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    
    @Aspect
    public class MyAspectAnno {
    
        // 前置通知
        // execution(* com.q.spring.demo1.OrderDao.save(..))
        @Before(value = "MyAspectAnno.pointcut1()")
        public void befor(){
            System.out.println("前置增强");
        }
    
        // 后置通知
        @AfterReturning(value = "MyAspectAnno.pointcut3()", returning = "result")
        public void afterReturning(Object result){
            System.out.println("后置增强 "+ result);
        }
    
    
        // 环绕通知
        @Around(value = "MyAspectAnno.pointcut2()")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
            System.out.println("环绕前增强");
            Object obj = joinPoint.proceed();
            System.out.println("环绕后增强");
            return obj;
        }
    
    
        // 异常抛出通知
        @AfterThrowing(value = "MyAspectAnno.pointcut4()", throwing = "e")
        public void afterThrowing(Throwable e){
            System.out.println("异常抛出增强: "+e);
        }
    
    
        // 最终通知
        @After(value = "MyAspectAnno.pointcut4()")
        public void afterThrowing(){
            System.out.println("最终增强");
        }
    
        // 切入点注解
        @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.save(..))")
        private void pointcut1(){}
        @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.update(..))")
        private void pointcut2(){}
        @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.delete(..))")
        private void pointcut3(){}
        @Pointcut(value = "execution(* com.q.spring.demo1.OrderDao.find(..))")
        private void pointcut4(){}
    }

     

    4. SpringDemo1.java 文件

    package com.q.spring.demo1;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SpringDemo1 {
    
        @Resource(name = "orderDao")
        private OrderDao orderDao;
    
        @Test
        public void demo1(){
            orderDao.save();
            orderDao.update();
            orderDao.delete();
            orderDao.find();
        }
    
    }


    九. Spring 的 JDBC 模板
    Spring 是一站式框架,有持久层解决方案

    1. DBCP 连接池
    # 文档..

    2. C3P0 连接池

    # 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"
           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">
    
            <!--  配置C3P0连接池  -->
    <!--        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">-->
    <!--                <property name="driverClass" value="com.mysql.jdbc.Driver" />-->
    <!--                <property name="jdbcUrl" value="jdbc:mysql:///spring_jdbc" />-->
    <!--                <property name="user" value="root" />-->
    <!--                <property name="password" value="chaoqi" />-->
    <!--        </bean>-->
    
            <!--  引入属性文件  -->
            <context:property-placeholder location="classpath:jdbc.properties" />
    
            <!--  配置C3P0连接池  -->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                    <property name="driverClass" value="${jdbc.driverClass}" />
                    <property name="jdbcUrl" value="${jdbc.url}" />
                    <property name="user" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
            </bean>
    
            <!--  配置 Spring 的JDBC的模板  -->
            <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
                    <property name="dataSource" ref="dataSource" />
            </bean>
    </beans>



    # 增删改查操作

    package com.q.jdbc.demo1;
    
    import com.q.jdbc.domain.Account;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowMapper;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.List;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class JdbcDemo2 {
    
        @Resource(name = "jdbcTemplate")
        private JdbcTemplate jdbcTemplate;
    
        //
        @Test
        public void demo1(){
            jdbcTemplate.update("insert into account values(null,?,?)","q4",152d);
        }
    
    
        //
        @Test
        public void demo2(){
            jdbcTemplate.update("update account set name=?, money = ? where id=? ","q1test",11d,2 );
        }
    
    
        //
        @Test
        public void demo3(){
            jdbcTemplate.update("delete from account where id=? ",2);
        }
    
        //
        @Test
        public void demo4(){
            String name = jdbcTemplate.queryForObject("select name from account where id=?",String.class,3);
            System.out.println(name);
        }
    
        // 统计查询
        @Test
        public void demo5(){
            Long count = jdbcTemplate.queryForObject("select count(*) from account",Long.class);
            System.out.println(count);
        }
    
        // 封装到一个对象中
        @Test
        public void demo6(){
            Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 3);
            System.out.println(account);
        }
    
        // 查询多条记录
        @Test
        public void demo7(){
            List<Account> list = jdbcTemplate.query("select * from account", new MyRowMapper());
            for(Account account : list){
                System.out.println(account);
            }
        }
    
    
        class MyRowMapper implements RowMapper<Account>{
    
            @Override
            public Account mapRow(ResultSet res, int rowNum) throws SQLException {
    
                Account account = new Account();
                account.setId(res.getInt("id"));
                account.setName(res.getString("name"));
                account.setMoney(res.getDouble("money"));
    
                return account;
            }
        }
    }



    十. Spring 的事务传播行为

    1. 报则保证多个操作在同一个事务中

    PROPAGATION_REQUIRED  : 默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来。
    PROPAGATION_SUPPORTS  : 支持事务
    ,如果A中有事务,使用A中的事务,如果没有,则不使用事务。
    PROPAGATION_MANDATORY : 如果A中有事务,使用A中的事务,如果A中没有事务,则抛异常。

    2. 保证多个操作不在同一个事务中

    PROPAGATION_REQUIRES_NEW  : 如果A中有事务,将A的事务挂起(暂停), 创建新事务,只包含自身操作。
                                如果A中没有事务,则创建一个新事务,包含自身操作
    PROPAGATION_NOT_SUPPORTED : 如果A中有事务,将A的事务挂起,不使用事务管理。
    PROPAGATION_NEVER           : 如果A中有事务,则抛异常。

    3. 嵌套式事务

    PROPAGATION_NESTED    : 嵌套事务,如果A中有事务,按照A的事务执行,执行完毕后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始的位置,也可以回滚到保存点。





    十一. Spring 声明式事务管理一 (XML)
    XML 步骤:
    1. 引入 aop 开发包。
    2. 配置事务管理器。
    3. 配置增强<tx:Advice>
    4. 配置aop

    # 1. 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/cache
            http://www.springframework.org/schema/cache/spring-cache.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">
    
    
            <!--  配置 Service  -->
            <bean id="accountService" class="com.q.tx.demo2.AccountServiceImpl">
                    <property name="accountDao" ref="accountDao" />
            </bean>
    
            <!--  配置 DAO  -->
            <bean id="accountDao" class="com.q.tx.demo2.AccountDaoImpl">
                    <property name="dataSource" ref="dataSource" />
            </bean>
    
            <!--  配置连接池的JDBC模板  -->
            <!--  引入属性文件  -->
            <context:property-placeholder location="classpath:jdbc.properties" />
    
            <!--  配置C3P0连接池  -->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                    <property name="driverClass" value="${jdbc.driverClass}" />
                    <property name="jdbcUrl" value="${jdbc.url}" />
                    <property name="user" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
            </bean>
    
            <!--  配置事务管理  -->
            <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="*" propagation="REQUIRED" />
    
                                <!--           实际开发中:            -->
    <!--                        <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" />-->
    <!--                        <tx:method name="update*" propagation="REQUIRED" />-->
    <!--                        <tx:method name="delete*" propagation="REQUIRED" />-->
    <!--                        <tx:method name="find*" read-only="true" />-->
                    </tx:attributes>
            </tx:advice>
            
            
            <!--  AOP的配置  -->
            <aop:config>
                    <aop:pointcut id="pointcut1" expression="execution(* com.q.tx.demo2.AccountServiceImpl.*(..))"/>
                    <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1" />
            </aop:config>
    </beans>
    # jdbc.propertie.xml 文件属性设置
    jdbc.driverClass=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///spring_jdbc
    jdbc.username=root
    jdbc.password=chaoqi



    # 2.  AccountDaoImpl.java 文件

    package com.q.tx.demo2;
    
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    // 转账Dao实现
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    
        @Override
        public void outMoney(Integer from, Double money) {
            this.getJdbcTemplate().update("update account set money = money - ? where id = ?", money, from);
        }
    
        @Override
        public void inMoney(Integer to, Double money) {
            this.getJdbcTemplate().update("update account set money = money + ? where id = ?", money, to);
        }
    }



    # 3. AccountServiceImpl.java 文件

    package com.q.tx.demo2;
    
    
    // 转账的业务层实现类
    public class AccountServiceImpl implements AccountService {
    
        // 注入 DAO
        private AccountDao accountDao;
    
        public void setAccountDao(AccountDao accountDao) {
            this.accountDao = accountDao;
        }
    
    
        /*
            from  : 转出账号
            to    : 转人账号
            money : 转账金额
            */
    
        @Override
        public void transfer(Integer from, Integer to, Double money) {
    
                    accountDao.outMoney(from, money);
    //                int i = 1/0;
                    accountDao.inMoney(to, money);
    
        }
    
    
    }



    # 4. 测试文件

    package com.q.tx.demo2;
    
    
    // 测试类
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:tx2.xml")
    public class SpringDemo1 {
    
        @Resource(name = "accountService")
        private AccountService accountService;
    
        @Test
        public void demo1(){
            accountService.transfer(1,3,100d);
        }
    
    }






    十二. Spring 声明式事务管理二 (注解方式)
    注解 步骤:
    1. 引入 aop 开发包。
    2. 配置事务管理器。
    3. 开启注解事务。
    4. 在业务层添加注解


    # 1. 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/cache
            http://www.springframework.org/schema/cache/spring-cache.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">
    
    
    
    
            <!--  配置 Service  -->
            <bean id="accountService" class="com.q.tx.demo3.AccountServiceImpl">
                    <property name="accountDao" ref="accountDao" />
            </bean>
    
            <!--  配置 DAO  -->
            <bean id="accountDao" class="com.q.tx.demo3.AccountDaoImpl">
                    <property name="dataSource" ref="dataSource" />
            </bean>
    
            <!--  配置连接池的JDBC模板  -->
            <!--  引入属性文件  -->
            <context:property-placeholder location="classpath:jdbc.properties" />
    
            <!--  配置C3P0连接池  -->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
                    <property name="driverClass" value="${jdbc.driverClass}" />
                    <property name="jdbcUrl" value="${jdbc.url}" />
                    <property name="user" value="${jdbc.username}" />
                    <property name="password" value="${jdbc.password}" />
            </bean>
    
            <!--  配置事务管理器 第一步  -->
            <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                    <property name="dataSource" ref="dataSource" />
            </bean>
    
            <!--  开启注解事务 第二步 -->
            <tx:annotation-driven transaction-manager="transactionManager" />
    </beans>




    # 2. AccountDaoImpl 文件

    package com.q.tx.demo3;
    
    
    import org.springframework.jdbc.core.support.JdbcDaoSupport;
    
    // 转账Dao实现
    public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {
    
        @Override
        public void outMoney(Integer from, Double money) {
            this.getJdbcTemplate().update("update account set money = money - ? where id = ?", money, from);
        }
    
        @Override
        public void inMoney(Integer to, Double money) {
            this.getJdbcTemplate().update("update account set money = money + ? where id = ?", money, to);
        }
    }



    # 3. AccountServiceImpl 文件

    package com.q.tx.demo3;
    
    
    import org.springframework.transaction.annotation.Transactional;
    
    // 转账的业务层实现类
    // 第三步 需要在要进行事务操作的类上加  @Transactional
    @Transactional
    public class AccountServiceImpl implements AccountService {
    
        // 注入 DAO
        private AccountDao accountDao;
    
        public void setAccountDao(AccountDao accountDao) {
            this.accountDao = accountDao;
        }
    
    
        /*
            from  : 转出账号
            to    : 转人账号
            money : 转账金额
            */
    
        @Override
        public void transfer(Integer from, Integer to, Double money) {
    
                    accountDao.outMoney(from, money);
    //                int i = 1/0;
                    accountDao.inMoney(to, money);
    
        }
    
    
    }


    # 4. 测试类

    package com.q.tx.demo3;
    
    
    // 测试类
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:tx3.xml")
    public class SpringDemo1 {
    
        @Resource(name = "accountService")
        private AccountService accountService;
    
        @Test
        public void demo1(){
            accountService.transfer(1,3,100d);
        }
    
    }




  • 相关阅读:
    HBase- 安装单机版HBase
    javascript中的设计模式之模板方法模式
    win 设置自动启动软件
    php高精度加减乘除
    frp实现内网穿透,实现夸服务器访问
    OCM 12c 直考预备知识点
    Oracle 19c New Features : Active Data Guard DML Redirect
    3级搭建类302-Oracle 19c RAC 双节点搭建
    VMWare WorkStation 15.5 配置RAC共享存储节点二无法识别共享磁盘UUID解决办法
    你还在争论 count(*) 与 count(column) 哪个更快?
  • 原文地址:https://www.cnblogs.com/chaoqi/p/10708500.html
Copyright © 2020-2023  润新知