今天內(nèi)容
- Spring框架的AOP之注解的方式
- Spring框架的JDBC模板
- 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.jaraspectJ的開發(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ù)分析之通知類型
- 通知類型
- @Before -- 前置通知
- @AfterReturing -- 后置通知
- @Around -- 環(huán)繞通知(目標(biāo)對(duì)象方法默認(rèn)不執(zhí)行的,需要手動(dòng)執(zhí)行)
- @After -- 最終通知
- @AfterThrowing -- 異常拋出通知
- 配置通用的切入點(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ù)概述
- Spring框架中提供了很多持久層的模板類來簡(jiǎn)化編程,使用模板類編寫程序會(huì)變的簡(jiǎn)單
- 提供了JDBC模板,Spring框架提供的
JdbcTemplate類
- 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.jarSpring-jdbc.jar
spring-jdbc-4.2.4.RELEASE.jarSpring-tx.jar
spring-tx-4.2.4.RELEASE.jar
3,引入applicationContext.xml和log4j.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.osgi和day35_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.jarcom.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ù)的回顧
- 事務(wù):指的是邏輯上一組操作,組成這個(gè)事務(wù)的各個(gè)執(zhí)行單元,要么一起成功,要么一起失?。?/li>
- 事務(wù)的特性
- 原子性
- 一致性
- 隔離性
- 持久性
- 如果不考慮隔離性,引發(fā)安全性問題
讀問題:
① 臟讀:
② 不可重復(fù)讀:
③ 虛讀:寫問題:
① 丟失更新:
- 如何解決安全性問題
- 讀問題解決,設(shè)置數(shù)據(jù)庫隔離級(jí)別
- 寫問題解決可以使用 悲觀鎖和樂觀鎖的方式解決