自定義註解是動態代理用的
基本的aop配置
一個介面DeptService
實現介面的類DeptServiceImpl,記得加上註解@Service,aop.xml掃描的時候會掃描到
有那個箭頭,表示這些方法都需要切入一些內容
新建類DeptLog
方法:
public void before(){ System.out.println("DeptLog:before..."); } public void afterReturning(){ System.out.println("DeptLog:afterReturning..."); } public void after(){ System.out.println("DeptLog: after ..."); } public Object around(ProceedingJoinPoint jp) throws Throwable{ System.out.println("DeptLog: around before ..."); Object o = jp.proceed();// 執行方法 System.out.println("DeptLog: around after ..."); return o; } public void exception(Exception e){ System.out.println("DeptLog exception ... "+e.toString()); }
新建spring-aop.xml的配置檔案,好測試
<context:component-scan base-package="com.zr"/> 掃描 <bean id="deptLog" class="com.zr.log.DeptLog"></bean> <aop:config>
設定aop的設定環境,即什麼方法需要切入
<aop:pointcut expression="execution(* com.zr..*(..))" id="deptPointcut"/>掃描
所有在com.zr下的任意包的任意方法都要被植入新的方法
<aop:pointcut expression="execution(* com.zr.service..up*(..))" id="updateDeptPointcut"/>掃描 <aop:aspect ref="deptLog"> <aop:before method="before" pointcut-ref="deptPointcut"/>//表示所有的方法都切入before方法 <aop:after-returning method="afterReturning" pointcut-ref="deptPointcut"/> <aop:after method="after" pointcut-ref="deptPointcut"/> <aop:around method="around" pointcut-ref="updateDeptPointcut" />//表示service包下的up開頭的方法都切入around方法 <aop:after-throwing method="exception" pointcut-ref="updateDeptPointcut" throwing="e"/> </aop:aspect> </aop:config>
測試的類AopTest
@Resource(name="deptService")
private DeptService service;
@Test
public void test() {
service.update();
}
20161123
<url-pattern>*.from</url-pattern>透過from表單提交的東西我這個分發器才做攔截,其他的不做攔截
AOP註解方式
aop.xml配置
<context:component-scan base-package="com.zr.service, com.zr.log"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>//true cglib的代理方式,jar包的
新建類DeptLog
記得加上Bean的註釋@Component以及用@Aspect宣告這是方面物件
@Component //不是控制器、服務層、資料庫訪問層都使用Component,通用的bean @Aspect //這是一個方面物件 public class DeptLog { @Before("execution(* com.zr.service..save*(..))")//只要符合這個插入規則就在這個範圍下的方法下切入方法 public void before(){ System.out.println("DeptLog:before..."); } @AfterReturning("execution(* com.zr.service..save*(..))") public void afterReturning(){ System.out.println("DeptLog:afterReturning..."); } @After("execution(* com.zr.service..*(..))") public void after(){// 最終通知 System.out.println("DeptLog: after ..."); } @Around("execution(* com.zr.service..update*(..))") public Object around(ProceedingJoinPoint jp) throws Throwable{ System.out.println("DeptLog: around before ..."); Object o = jp.proceed();// 執行方法 System.out.println("DeptLog: around after ..."); return o; } @AfterThrowing(pointcut="execution(* com.zr.service..*(..))", throwing="e") public void afterThrowing(Exception e){ System.out.println("DeptLog exception ... " + e.toString()); } }
在類DeptLog的方法上寫註解寫規則
測試類AopTest:
@Resource(name="deptService")
private DeptService service;
@Test
public void test() {
service.save();
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
service.update();
System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$");
service.delete();
}
//---------------------------------------------------------------------------------------------------
事務:
在spring-db.xml檔案增加
宣告事務管理元件
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
配置宣告事物的範圍及型別
<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<tx:attributes>
記得新增回滾屬性
<tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="java.sql.SQLException"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="find*" read-only="true"/>
</tx:attributes>
</tx:advice>
使用AOP配置那些操作需要事務
<aop:config proxy-target-class="true"> //proxy-target-class="true"使用什麼代理,設定為true表示cglp動態代理
(動態代理用兩種,一種JDK自帶一種cglp,區別JDK自帶的代理對沒介面的類不進行代理)
***service下的所有方法都新增了上面的事務***
<aop:advisor advice-ref="transactionAdvice" pointcut="execution(* com.zr.service..*(..))" />//在service包下切入事務
</aop:config>
隔離不代表回滾,rollback-for="java.sql.SQLException"當出現sql異常時候回滾
測試:
@Resource
private DeptService service;
@Test
public void test() {
Dept d1 = new Dept();
d1.setDeptno(90);
d1.setDname("0901開發班");
d1.setLoc("車陂");
service.save(d1);
d1 = new Dept();
d1.setDeptno(90);
d1.setDname("0902開發班");
d1.setLoc("車陂");
service.save(d1);
}
一次增加兩個同樣id的,會先把第一個80增加進去,然後資料庫就有了,但是下面那個80在執行的時候會丟擲異常說明有了
捕獲這個異常,rollback-for="java.sql.SQLException"有了就回滾,兩個都增加不進去
事務註解:db.xml下增加
<!-- 宣告事務管理元件,DataSourceTransactionManager,無論使用註解還是配置XML方式都必須有 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 使用註解方式實現事務控制 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
在DeptServiceImpl這個類新增註解@Transactional(isolation=Isolation.READ_COMMITTED, rollbackFor=java.sql.SQLException.class)
/*
* 給當前類新增上事務控制
* @Transactional 可以新增在類上或方法上,如果在類上就是對本類的所有方法實現同樣事務處理方式
* 如果是在方法,只針對新增註解的方法
*/