AOP注解開發(fā)光速入門
- 步驟一:引入相關(guān)的jar及配置文件
* 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
引入AOP約束
<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>
- 步驟二:編寫目標(biāo)類
public class ProductDao {
public void save(){
System.out.println("保存商品...");
}
public void update(){
System.out.println("修改商品...");
}
public void delete(){
System.out.println("刪除商品...");
}
public void find(){
System.out.println("查詢商品...");
}
}
<!-- 目標(biāo)類============ -->
<bean id="productDao" class="cn.itcast.spring.demo4.ProductDao"></bean>
- 步驟三:開啟aop注解自動代理
<aop:aspectj-autoproxy/>
- 常用AspectJ 的AOP注解
@Aspect:定義切面類的注解
通知類型:
* @Before :前置通知
* @AfterReturing :后置通知
* @Around :環(huán)繞通知
* @After :最終通知
* @AfterThrowing :異常拋出通知.
@Pointcut:定義切入點的注解
- ** 步驟四:編寫切面類**
@Aspect
public class MyAspectAnno {
@Before("MyAspectAnno.pointcut1()")
public void before(){
System.out.println("前置通知===========");
}
@Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.save(..))")
private void pointcut1(){}
}
<!-- 配置切面類 -->
<bean id="myAspectAnno" class="cn.itcast.spring.demo4.MyAspectAnno"></bean>
- 步驟五:其他通知的注解
@Aspect
public class MyAspectAnno {
@Before("MyAspectAnno.pointcut1()")
public void before(){
System.out.println("前置通知===========");
}
@AfterReturning("MyAspectAnno.pointcut2()")
public void afterReturning(){
System.out.println("后置通知===========");
}
@Around("MyAspectAnno.pointcut3()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("環(huán)繞前通知==========");
Object obj = joinPoint.proceed();
System.out.println("環(huán)繞后通知==========");
return obj;
}
@AfterThrowing("MyAspectAnno.pointcut4()")
public void afterThrowing(){
System.out.println("異常拋出通知========");
}
@After("MyAspectAnno.pointcut4()")
public void after(){
System.out.println("最終通知==========");
}
@Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.save(..))")
private void pointcut1(){}
@Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.update(..))")
private void pointcut2(){}
@Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.delete(..))")
private void pointcut3(){}
@Pointcut("execution(* cn.itcast.spring.demo4.ProductDao.find(..))")
private void pointcut4(){}
}
Spring與JDBC整合
-
Spring 提供了很多持久層技術(shù)的模板類簡化編程
其實就是提供了一個可以進行數(shù)據(jù)庫操作的對象牍帚,封裝了JDBC技術(shù)
- 使用入門
-
步驟一:引入相關(guān)開發(fā)包
- 步驟二:創(chuàng)建一個測試類
@Test
// JDBC 模板的基本使用:
public void demo1(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql:///spring_day03");
dataSource.setUsername("root");
dataSource.setPassword("123");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update("insert into account values (null,?,?)", " 會 希
",10000d);
}
-
步驟三:將連接池的配置交給Spring管理
- 1.Spring 內(nèi)置的連接池的配置
<!-- 配置 Spring 的內(nèi)置連接池 -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_day02"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
```
測試類編寫
**** 引入 spring-aop.jar
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo2 {
@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Test
public void demo1(){
jdbcTemplate.update("insert into account values (null,?,?)", " 鳳 姐
",10000d);
}
}
- **2.Spring中配置DBCP連接池**
【引入dbcp連接池的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_day02"/>
<property name="username" value="root"/>
<property name="password" value="123"/>
</bean>
- **Spring中配置c3p0連接池**
【引入相應(yīng)的 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_day02"/>
<property name="user" value="root"/>
<property name="password" value="123"/>
</bean>
- 步驟四: JDBC模板CRUD的操作
RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo3 {
@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Test
// 插入操作
public void demo1(){
jdbcTemplate.update("insert into account values (null,?,?)", " 冠 希
",10000d);
}
@Test
// 修改操作
public void demo2(){
jdbcTemplate.update("update account set name=?,money =? where id = ?", "
思雨",10000d,5);
}
@Test
// 刪除操作
public void demo3(){
jdbcTemplate.update("delete from account where id = ?", 5);
}
@Test
// 查詢一條記錄
public void demo4(){
Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new MyRowMapper(), 1);
System.out.println(account);
}
@Test
// 查詢所有記錄
public void demo5(){
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 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;
}
}
}
-
Spring中控制事務(wù)
- 事務(wù)回顧
什么是事務(wù):
事務(wù)邏輯上的一組操作,組成這組操作的各個邏輯單元,要么一起成功,要么一起失敗
事務(wù)特性:
原子性 :強調(diào)事務(wù)的不可分割.
一致性 :事務(wù)的執(zhí)行的前后數(shù)據(jù)的完整性保持一致.
隔離性 :一個事務(wù)執(zhí)行的過程中,不應(yīng)該受到其他事務(wù)的干擾
持久性 :事務(wù)一旦結(jié)束,數(shù)據(jù)就持久到數(shù)據(jù)庫
如果不考慮隔離性引發(fā)安全性問題:
臟讀 :一個事務(wù)讀到了另一個事務(wù)的未提交的數(shù)據(jù)
不可重復(fù)讀 :一個事務(wù)讀到了另一個事務(wù)已經(jīng)提交的 update 的數(shù)據(jù)導(dǎo)致多次查詢結(jié)果不一致.
虛幻讀 :一個事務(wù)讀到了另一個事務(wù)已經(jīng)提交的 insert 的數(shù)據(jù)導(dǎo)致多次查詢結(jié)果不一致.
解決讀問題: 設(shè)置事務(wù)隔離級別
未提交讀 :臟讀晦嵌,不可重復(fù)讀腋逆,虛讀都有可能發(fā)生
已提交讀 :避免臟讀败京。但是不可重復(fù)讀和虛讀有可能發(fā)生
可重復(fù)讀 :避免臟讀和不可重復(fù)讀.但是虛讀有可能發(fā)生.
串行化的 :避免以上所有讀問題.
Mysql 默認(rèn):可重復(fù)讀
Oracle 默認(rèn):讀已提交
- Spring PlatformTransactionManager: 平臺事務(wù)管理器
***** 真正管理事務(wù)的對象
org.springframework.jdbc.datasource.DataSourceTransactionManager 使用SpringJDBC或iBatis進行持久化數(shù)據(jù)時使用
org.springframework.orm.hibernate3.HibernateTransactionManager 使用Hibernate進行持久化數(shù)據(jù)時使用
- TransactionDefinition:事務(wù)定義信息
事務(wù)定義信息:
* 隔離級別
* 傳播行為
* 超時信息
* 是否只讀
- TransactionStatus:記錄事務(wù)的狀態(tài)
- 事務(wù)的傳播行為
PROPAGION_XXX :事務(wù)的傳播行為
* 保證同一個事務(wù)中
PROPAGATION_REQUIRED 支持當(dāng)前事務(wù)颈嚼,如果不存在 就新建一個(默認(rèn))
PROPAGATION_SUPPORTS 支持當(dāng)前事務(wù),如果不存在饲嗽,就不使用事務(wù)PROPAGATION_MANDATORY 支持當(dāng)前事務(wù)屁倔,如果不存在票罐,拋出異常
* 保證沒有在同一個事務(wù)中
PROPAGATION_REQUIRES_NEW 如果有事務(wù)存在叉趣,掛起當(dāng)前事務(wù),創(chuàng)建一個新的事務(wù)
PROPAGATION_NOT_SUPPORTED 以非事務(wù)方式運行该押,如果有事務(wù)存在疗杉,掛起當(dāng)前事務(wù)
PROPAGATION_NEVER 以非事務(wù)方式運行,如果有事務(wù)存在蚕礼,拋出異常
PROPAGATION_NESTED 如果當(dāng)前事務(wù)存在烟具,則嵌套事務(wù)執(zhí)行
- Spring聲明式事務(wù)管理XML方式 思想就是 AOP
配置事務(wù)管理器
<!-- 事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
配置事務(wù)的通知
<!-- 配置事務(wù)的增強 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!--
isolation="DEFAULT" 隔離級別
propagation="REQUIRED" 傳播行為
read-only="false" 只讀
timeout="-1" 過期時間
rollback-for="" -Exception
no-rollback-for="" +Exception
-->
<tx:method name="transfer" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
配置 aop
<aop:config>
<aop:pointcut expression="execution(*cn.itcast.transaction.demo2.AccountServiceImpl.transfer(..))" id="pointcut1"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/>
</aop:config>
- Spring聲明式事務(wù)管理 注解方式
<!-- 配置事務(wù)管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 開啟注解事務(wù)管理 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
-
在使用事務(wù)的類上添加一個注解:@Transactional