六、AOP基本使用
阿新 • • 發佈:2018-11-22
1.傳統的IOC測試方法:
- 前提:
需要手動載入配置檔案(工廠), 強制轉型,需要在配置檔案中配置bean
- 程式碼:
@Test
public void test(){
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
User user =(User) app.getBean("user");
System.out.println(user.name); //Hello Spring!
System.out.println(user.dog.name); //wc
}
2.使用AOP註解的測試方法
- 前提:
註解形式,不需要轉型,需要在配置檔案中配置實現類的掃描
- 程式碼:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name="goodsDao")
private GoodsDao goodsDao;
@Test
public void test(){
this.goodsDao.save();
}
}
3.AOP切面程式設計
- 編寫GoodsDao介面和實現類
//介面
package com.itlike.demo2;
public interface GoodsDao {
public void save();
}
//實現類
package com.itlike.demo2;
public class GoodsDaoImpl implements GoodsDao {
@Override
public void save() {
System.out.println("儲存操作");
}
}
- 編寫切面類(即要新增的功能類)
package com.itlike.demo2;
public class MyAspect {
public void check(){
System.out.println("許可權校驗");
}
}
- 編寫配置檔案
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: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="goodsDao" class="com.itlike.demo2.GoodsDaoImpl"/>
<bean id="myaspect" class="com.itlike.demo2.MyAspect"/>
<!--配置AOP-->
<aop:config>
<!--配置切入點:給哪個方法進行增強-->
<aop:pointcut id="savepoint" expression="execution(* com.itlike.demo2.GoodsDaoImpl.save(..))"/>
<!--配置切面:增強的功能是什麼-->
<aop:aspect ref="myaspect">
<!--前置通知-->
<aop:before method="check" pointcut-ref="savepoint"/>
</aop:aspect>
</aop:config>
</beans>
- 編寫AOP測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name = "goodsDao")
private GoodsDao goodsDao;
@Test
public void test() {
this.goodsDao.save();
}
}
//許可權校驗
//儲存操作
4.前置通知 (如上)
- 在目標方法執行之前進行操作
5.後置通知
- 在目標方法執行之後 進行操作
- 切面方法
//切面類新增方法
public void log(){
System.out.println("日誌記錄");
}
- 配置檔案:
<?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="goodsDao" class="com.itlike.demo2.GoodsDaoImpl"/>
<bean id="myaspect" class="com.itlike.demo2.MyAspect"/>
<!--配置AOP-->
<aop:config>
<!--配置切入點:給哪個方法進行增強-->
<aop:pointcut id="savepoint" expression="execution(* com.itlike.demo2.GoodsDaoImpl.save(..))"/>
<!--配置切面:增強的功能是什麼-->
<aop:aspect ref="myaspect">
<!--前置通知-->
<aop:before method="check" pointcut-ref="savepoint"/>
<!--後置通知-->
<aop:after-returning method="log" pointcut-ref="savepoint"/>
</aop:aspect>
</aop:config>
</beans>
- 執行測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name = "goodsDao")
private GoodsDao goodsDao;
@Test
public void test() {
this.goodsDao.save();
}
}
//許可權校驗
//儲存操作
//日誌記錄
- 後置通知可以取得方法的返回值:
- 更改Dao介面和實現類的返回值型別為void–>String,並返回"success":
//介面
public interface GoodsDao {
public String save();
}
//實現類
public class GoodsDaoImpl implements GoodsDao {
@Override
public String save() {
System.out.println("儲存操作");
return "success";
}
}
- 切面類MyAspect中的後置通知方法增添引數Object res (用res取得切入點的返回值),並列印輸出:
public void log(Object res){
System.out.println("日誌記錄"+res);
}
- 配置檔案的後置通知增加return屬性:(res必須和上面的方法引數res命名一致)
<!--後置通知-->
<aop:after-returning method="log" pointcut-ref="savepoint" returning="res"/>
- 執行測試類,可以得到結果如下:
//許可權校驗
//儲存操作
//日誌記錄success
6. 環繞通知
- 在目標方法執行之前 和之後進行操作
- 宣告Dao介面和實現類:
//介面
public interface GoodsDao {
public void delete();
}
//實現類
public class GoodsDaoImpl implements GoodsDao {
@Override
public void delete() {
System.out.println("刪除操作");
}
}
- 編寫切面類方法:
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("環繞前通知");
/*執行切入點方法*/
Object proceed = joinPoint.proceed();
System.out.println("環繞後通知");
return proceed;
}
- 配置檔案
applicationContext.xml
<aop:pointcut id="deletepoint" expression="execution(* com.itlike.demo2.GoodsDaoImpl.delete(..))"/>
<aop:aspect ref="myaspect">
<!--環繞通知-->
<aop:around method="around" pointcut-ref="deletepoint"/>
</aop:aspect>
- 執行測試方法:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name = "goodsDao")
private GoodsDao goodsDao;
@Test
public void test() {
this.goodsDao.delete();
}
}
//環繞前通知
//刪除操作
//環繞後通知
7.異常丟擲通知
- 在程式出現異常時進行操作
- 宣告Dao介面和實現類:
//介面
public interface GoodsDao {
public void find();
}
//實現類
public class GoodsDaoImpl implements GoodsDao {
@Override
public void find() {
System.out.println("炒作操作");
int i=1/0; //會發生除0異常
}
}
- 編寫切面類方法:
public void Myexception(Throwable ex){
System.out.println("異常通知"+ex.getMessage());
}
- 配置檔案
applicationContext.xml
<aop:pointcut id="findpoint" expression="execution(* com.itlike.demo2.GoodsDaoImpl.find(..))"/>
<aop:aspect ref="myaspect">
<!--異常通知-->
<aop:after-throwing method="Myexception" pointcut-ref="findpoint" throwing="ex"/>
</aop:aspect>
- 執行測試方法:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
@Resource(name = "goodsDao")
private GoodsDao goodsDao;
@Test
public void test() {
this.goodsDao.find();
}
}
//查詢操作
//異常通知/ by zero
8.最終通知
- 無論程式碼是否有異常,都會執行
<!--最終通知-->
<aop:after method="after" pointcut-ref="findpoint"/>