03_Spring

今天內(nèi)容

  1. Spring框架的AOP之注解的方式
  2. Spring框架的JDBC模板
  3. Spring框架的事務(wù)管理

案例一:使用Spring框架的AOP技術(shù)對(duì)DAO層的功能進(jìn)行增強(qiáng)

  • 使用Spring框架的AOP技術(shù)對(duì)DAO層的功能進(jìn)行增強(qiáng)

技術(shù)分析之:Spring框架的AOP技術(shù)(注解方式)
1, 步驟一:創(chuàng)建JavaWEB項(xiàng)目(本例名稱為day37_aop),引入具體的開發(fā)的jar包

  • 先引入Spring框架開發(fā)的基本開發(fā)包

  • 再引入Spring框架的AOP的開發(fā)包

  • spring的傳統(tǒng)AOP的開發(fā)的包
    spring-aop-4.2.4.RELEASE.jar
    com.springsource.org.aopalliance-1.0.0.jar

  • aspectJ的開發(fā)包
    com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
    spring-aspects-4.2.4.RELEASE.jar

2, 步驟二:創(chuàng)建Spring的配置文件,引入具體的AOP的schema約束

 <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>

3, 步驟三:創(chuàng)建包結(jié)構(gòu),編寫具體的接口和實(shí)現(xiàn)類

  • com.itheima.demo1
  • CustomerDao -- 接口
  • CustomerDaoImpl -- 實(shí)現(xiàn)類

4, 步驟四:將目標(biāo)類配置到Spring中
<bean id="customerDao" class="com.itheima.demo1.CustomerDaoImpl"/>

5, 步驟五:定義切面類
① 添加切面和通知的注解

  • @Aspect -- 定義切面類的注解

  • 通知類型(注解的參數(shù)是切入點(diǎn)的表達(dá)式)

  • @Before -- 前置通知

  • @AfterReturing -- 后置通知

  • @Around -- 環(huán)繞通知

  • @After -- 最終通知

  • @AfterThrowing -- 異常拋出通知

② 具體的代碼如下

 @Aspect
 public class MyAspectAnno {
 @Before(value="execution(public void com.itheima.demo1.CustomerDaoImpl.save())")
 public void log(){
 System.out.println("記錄日志...");
 }
 }

6, 步驟六:在配置文件中定義切面類
<bean id="myAspectAnno" class="com.itheima.demo1.MyAspectAnno"/>

7, 步驟七:在配置文件中開啟自動(dòng)代理
<aop:aspectj-autoproxy/>

8, 完成測(cè)試

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:applicationContext.xml")
 public class Demo1 {
 
 @Resource(name="customerDao")
 private CustomerDao customerDao;
 
 @Test
 public void run1(){
 customerDao.save();
 customerDao.update();
 }
 }


例:使用注解完成AspectJ的AOP開發(fā)
1, 新建JavaWEB項(xiàng)目(本例名稱為day37_aop)
2, 導(dǎo)入jar包,參考上面步驟,本例導(dǎo)入所有jar包如下:
com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.apache.commons.logging-1.1.1.jar com.springsource.org.apache.log4j-1.2.15.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aop-4.2.4.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar spring-beans-4.2.4.RELEASE.jar spring-context-4.2.4.RELEASE.jar spring-core-4.2.4.RELEASE.jar spring-expression-4.2.4.RELEASE.jar spring-test-4.2.4.RELEASE.jar
3, 在src目錄下引入log4j.properties,參考spring以前筆記

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

4,類和接口如下:

package com.huachao.demo1;

public interface CustomerDao {
    public void save();
    public void update();
}

public class CustomerDaoImp implements CustomerDao {
    @Override
    public void save() {
        System.out.println("客戶 保存...");
    }
    @Override
    public void update() {
        System.out.println("客戶 更新...");
    }
}

5,使用注解的切面類

package com.huachao.demo1;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class MyAspectJAnnotation {
    @Before(value="execution(* com.huachao.demo1.CustomerDaoImp.save(..))")
    public void log()
    {
        System.out.println("記錄日志...");
    }
}

6,在src目錄下新建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">
    
    <bean id="customerDao" class="com.huachao.demo1.CustomerDaoImp"/>
    <bean id="myAspectJAnnotation" class="com.huachao.demo1.MyAspectJAnnotation"/>
    
    <aop:aspectj-autoproxy/>
</beans>

7,測(cè)試類如下:

package com.huachao.demo1;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo1 {
    @Resource(name="customerDao")
    public CustomerDao customerDao;
    @Test
    public void Run1()
    {
        customerDao.save();
        customerDao.update();
    }
}

技術(shù)分析之通知類型

  1. 通知類型
  • @Before      -- 前置通知
  • @AfterReturing   -- 后置通知
  • @Around     -- 環(huán)繞通知(目標(biāo)對(duì)象方法默認(rèn)不執(zhí)行的,需要手動(dòng)執(zhí)行)
  • @After       -- 最終通知
  • @AfterThrowing   -- 異常拋出通知
  1. 配置通用的切入點(diǎn)
  • 使用@Pointcut定義通用的切入點(diǎn)
 @Aspect
 public class MyAspectAnno {
 @Before(value="MyAspectAnno.fn()")
 public void log(){
 System.out.println("記錄日志...");
 }
 @Pointcut(value="execution(public void com.itheima.demo1.CustomerDaoImpl.save())")
 public void fn(){}
 }

例:通知類型

package com.huachao.demo1;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class MyAspectJAnnotation {
    /*
     * 通知類型:@Before前置通知(切入點(diǎn)表達(dá)式)
     */
    //@Before(value="execution(* com.huachao.demo1.CustomerDaoImp.save(..))")
    /*
     * 引入自定義切入點(diǎn)
     */
    @Before(value="MyAspectJAnnotation.fn()")
    public void log()
    {
        System.out.println("記錄日志...");
    }
    
    /**
     * 最終通知:方法執(zhí)行成功或者出現(xiàn)異常,都會(huì)執(zhí)行
     */
    //@After(value="execution(* com.huachao.demo1.CustomerDaoImp.save(..))")
    /*
     * 引入自定義切入點(diǎn)
     */
    @After(value="MyAspectJAnnotation.fn()")
    public void after()
    {
        System.out.println("記錄日志...");
    }
    
    /**
     * 自定義切入點(diǎn)
     * 必須依賴方法,但是這個(gè)方法名隨意
     */
    @Pointcut(value="execution(* com.huachao.demo1.CustomerDaoImp.save(..))")
    public void fn(){}
    
    
    /**
     * 環(huán)繞通知(目標(biāo)對(duì)象方法默認(rèn)不執(zhí)行的,需要手動(dòng)執(zhí)行)
     * @param joinPoint
     */
    @Around(value="MyAspectJAnnotation.fn()")
    public void around(ProceedingJoinPoint joinPoint)
    {
        System.out.println("環(huán)繞前...");
        try {
            joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("環(huán)繞后...");
    }
    
}


案例二:Spring框架的事務(wù)管理完成轉(zhuǎn)賬的案例


需求分析

  • 完成一個(gè)轉(zhuǎn)賬的功能,需要進(jìn)行事務(wù)的管理,使用Spring的事務(wù)管理的方式完成

Spring框架的JDBC模板技術(shù)


技術(shù)分析之Spring框架的JDBC模板技術(shù)概述

  1. Spring框架中提供了很多持久層的模板類來簡(jiǎn)化編程,使用模板類編寫程序會(huì)變的簡(jiǎn)單
  2. 提供了JDBC模板,Spring框架提供的
  • JdbcTemplate類
  1. Spring框架可以整合Hibernate框架,也提供了模板類
  • HibernateTemplate類

技術(shù)分析之演示JDBC的模板類
1, 步驟一:創(chuàng)建數(shù)據(jù)庫的表結(jié)構(gòu)

 create database spring_day03;
 use spring_day03;
 create table t_account(
 id int primary key auto_increment,
 name varchar(20),
 money double
 );

2, 引入開發(fā)的jar包

  • 先引入IOC基本的6個(gè)jar包
    com.springsource.org.apache.commons.logging-1.1.1.jar com.springsource.org.apache.log4j-1.2.15.jar spring-beans-4.2.4.RELEASE.jar spring-context-4.2.4.RELEASE.jar spring-core-4.2.4.RELEASE.jar spring-expression-4.2.4.RELEASE.jar

  • 再引入Spring-aop的jar包
    spring-aop-4.2.4.RELEASE.jar

  • 最后引入JDBC模板需要的jar包

  • MySQL數(shù)據(jù)庫的驅(qū)動(dòng)包
    本例使用mysql:mysql-connector-java-5.1.7-bin.jar

  • Spring-jdbc.jar
    spring-jdbc-4.2.4.RELEASE.jar

  • Spring-tx.jar
    spring-tx-4.2.4.RELEASE.jar

3,引入applicationContext.xmllog4j.properties配置文件

4, 編寫測(cè)試代碼(自己來new對(duì)象的方式)

@Test
    public void Run1()
    {
        // Spring框架提供了內(nèi)置的連接池,不想使用內(nèi)置,可以整合其他的連接池
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_day03");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        
        //創(chuàng)建模板類
        JdbcTemplate template = new JdbcTemplate();
        //設(shè)置連接池
        template.setDataSource(dataSource);
        //完成操作
        template.update("insert into t_account values (null,?,?)","冠希",1000);
    }


技術(shù)分析之使用Spring框架來管理模板類
1, 剛才編寫的代碼使用的是new的方式,應(yīng)該把這些類交給Spring框架來管理。
2, 修改的步驟如下

  • 步驟一:Spring管理內(nèi)置的連接池

    <!-- 配置Spring提供的連接池 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_day03"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
  • 步驟二:Spring管理模板類
<!-- 配置JDBC模板 -->

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>
  • 步驟三:編寫測(cè)試程序
package com.huachao.demo1;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo2 {
    @Resource(name="jdbcTemplate")
    private JdbcTemplate template;
    @Test
    public void Run1()
    {
        template.update("insert into t_account values (null,?,?)","冠希2",1000);
    }
}

技術(shù)分析之Spring框架管理開源的連接池
1, 管理DBCP連接池

  • 先引入DBCP的2個(gè)jar包,在day35_Spring01\資料\spring-framework-3.0.2.RELEASE-dependencies\org.apache.commons\com.springsource.org.apache.commons.dbcp\1.2.2.osgiday35_Spring01\資料\spring-framework-3.0.2.RELEASE-dependencies\org.apache.commons\com.springsource.org.apache.commons.pool\1.5.3目錄下

  • com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar

  • com.springsource.org.apache.commons.pool-1.5.3.jar

  • 編寫配置文件


    <!-- 配置DBCP連接池 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///spring_day03"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

2, 管理C3P0連接池

  • 先引入C3P0的jar包,在day35_Spring01\資料\spring-framework-3.0.2.RELEASE-dependencies\com.mchange.c3p0\com.springsource.com.mchange.v2.c3p0\0.9.1.2目錄下

  • com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar

  • 編寫配置文件


    <!-- 配置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_day03"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>

技術(shù)分析之Spring框架的JDBC模板的簡(jiǎn)單操作

  • 增刪改查的操作
package com.huachao.demo1;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import javax.annotation.Resource;
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;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo2 {
    @Resource(name="jdbcTemplate")
    private JdbcTemplate template;
    /**
     * 插入
     */
    @Test
    public void Run1()
    {
        template.update("insert into t_account values (null,?,?)","冠希4",1000);
    }
    /**
     * 修改
     */
    @Test
    public void Run2()
    {
        template.update("update t_account set name=? where id=?","美美",3);
    }
    /**
     * 刪除
     */
    @Test
    public void Run3()
    {
        template.update("delete from t_account where id=?",4);
    }
    /**
     * 查詢一條數(shù)據(jù)
     */
    @Test
    public void Run4()
    {
        Account ac = template.queryForObject("select * from t_account where id=?", new BeanMapper(), 1);
        System.out.println(ac.toString());
    }
    /**
     * 查詢所有數(shù)據(jù)
     */
    @Test
    public void Run5()
    {
        List<Account> list = template.query("select * from t_account", new BeanMapper());
        System.out.println(list);
    }
    class BeanMapper implements RowMapper<Account>{
        @Override
        public Account mapRow(ResultSet rs, int rowNum) throws SQLException {
            Account account = new Account();
            account.setId(rs.getInt("id"));
            account.setName(rs.getString("name"));
            account.setMoney(rs.getDouble("money"));
            return account;
        }
    }
}

技術(shù)分析之Spring框架的事務(wù)管理


技術(shù)分析之事務(wù)的回顧

  1. 事務(wù):指的是邏輯上一組操作,組成這個(gè)事務(wù)的各個(gè)執(zhí)行單元,要么一起成功,要么一起失?。?/li>
  2. 事務(wù)的特性
  • 原子性
  • 一致性
  • 隔離性
  • 持久性
  1. 如果不考慮隔離性,引發(fā)安全性問題
  • 讀問題:
    ① 臟讀:
    ② 不可重復(fù)讀:
    ③ 虛讀:

  • 寫問題:
    ① 丟失更新:

  1. 如何解決安全性問題
  • 讀問題解決,設(shè)置數(shù)據(jù)庫隔離級(jí)別
  • 寫問題解決可以使用 悲觀鎖和樂觀鎖的方式解決

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容