1. 程式人生 > >六、AOP基本使用

六、AOP基本使用

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.後置通知

  • 在目標方法執行之後 進行操作
  1. 切面方法
//切面類新增方法
public void log(){
    System.out.println("日誌記錄");
}
  1. 配置檔案:
<?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>
  1. 執行測試類
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Resource(name = "goodsDao")
    private GoodsDao goodsDao;

    @Test
    public void test() {
        this.goodsDao.save();
    }
}
//許可權校驗
//儲存操作
//日誌記錄
  • 後置通知可以取得方法的返回值:
  1. 更改Dao介面和實現類的返回值型別為void–>String,並返回"success":
//介面
public interface GoodsDao {
    public String save();
}
//實現類
public class GoodsDaoImpl implements GoodsDao {
    @Override
    public String save() {
        System.out.println("儲存操作");
        return "success";
    }
}
  1. 切面類MyAspect中的後置通知方法增添引數Object res (用res取得切入點的返回值),並列印輸出:
public void log(Object res){
    System.out.println("日誌記錄"+res);
}
  1. 配置檔案的後置通知增加return屬性:(res必須和上面的方法引數res命名一致)
<!--後置通知-->
<aop:after-returning method="log" pointcut-ref="savepoint" returning="res"/>
  1. 執行測試類,可以得到結果如下:
//許可權校驗
//儲存操作
//日誌記錄success

6. 環繞通知

  • 在目標方法執行之前 和之後進行操作
  1. 宣告Dao介面和實現類:
//介面
public interface GoodsDao {
    public void delete();
}
//實現類
public class GoodsDaoImpl implements GoodsDao {    
    @Override
    public void delete() {
        System.out.println("刪除操作");
    }
}
  1. 編寫切面類方法:
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
    System.out.println("環繞前通知");
    /*執行切入點方法*/
    Object proceed = joinPoint.proceed();
    System.out.println("環繞後通知");
    return proceed;
}
  1. 配置檔案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>
  1. 執行測試方法:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Resource(name = "goodsDao")
    private GoodsDao goodsDao;

    @Test
    public void test() {
        this.goodsDao.delete();
    }
}
//環繞前通知
//刪除操作
//環繞後通知

7.異常丟擲通知

  • 在程式出現異常時進行操作
  1. 宣告Dao介面和實現類:
//介面
public interface GoodsDao {
    public void find();
}
//實現類
public class GoodsDaoImpl implements GoodsDao {    
    @Override
    public void find() {
        System.out.println("炒作操作");
        int i=1/0; //會發生除0異常 
    }
}
  1. 編寫切面類方法:
public void Myexception(Throwable ex){
    System.out.println("異常通知"+ex.getMessage());
}
  1. 配置檔案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>
  1. 執行測試方法:
@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"/>