1. 程式人生 > >Spring(九)--通知

Spring(九)--通知

tac 一個 方法體 width mage 代理 system cti sad

SpringAdvice通知

Spring原生的經典模式 實現AOP
advice :通知
前置通知:在目標方法執行之前執行!不能改變方法的執行流程和結果!
實現MethodBeforeAdvice接口!
後置通知:在目標方法執行之後執行!不能改變方法的執行流程和結果!
實現AfterReturningAdvice接口!
環繞通知:方法的攔截器!進入了方法體,能改變方法的執行流程和結果!
實現MethodInterceptor接口!
異常通知: 當我們的目標方法發生異常才會被執行!
實現ThrowsAdvice接口!

如果想在項目中使用各種通知,必須引入需要的

pom文件節點!
01.aop聯盟
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
02. spring整合aop的jar
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>

1. 創建需要的dao接口

技術分享圖片

2. 創建需要的daoImpl實現類

技術分享圖片

3. 創建前置增強類

技術分享圖片

4. 創建後置增強類

技術分享圖片

5. 創建環繞增強類

技術分享圖片

6. 創建異常增強類和自定義異常類

技術分享圖片

技術分享圖片

7. 配置spring.xml文件

 <!--01. 配置目標對象   實際肯定是配置UserServiceImpl-->
    <bean id="userDaoImpl" class="com.xdf.dao.UserDaoImpl"/>

    <!--02.配置各種通知-->
    <!--001.前置通知-->
    <bean id="beforeAdvice" class
="com.xdf.advice.BeforeAdvice"/> <!--002.後置通知--> <bean id="afterAdvice" class="com.xdf.advice.AfterAdvice"/> <!--003.環繞通知--> <bean id="aroundAdvice" class="com.xdf.advice.AroundAdvice"/> <!--004.異常通知--> <bean id="exceptionAdvice" class="com.xdf.advice.ExceptionAdvice"/> <!--03.需要配置代理工廠bean,來創建代理類! 從而把各種通知織入到目標對象的目標方法中--> <bean id="userProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!--註冊了目標對象--> <property name="targetName" value="userDaoImpl"/> <!--註冊通知--> <property name="interceptorNames"> <array> <value>beforeAdvice</value><!--前置通知--> <value>afterAdvice</value><!--後置通知--> <value>aroundAdvice</value><!--環繞通知--> </array> </property> </bean> <!--再次創建一個工廠 來為異常對象服務 因為一個工廠無法為多個對象服務--> <bean id="exceptionProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!--註冊了目標對象--> <property name="targetName" value="userDaoImpl"/> <!--註冊通知--> <property name="interceptorNames"> <array> <value>exceptionAdvice</value><!--異常通知--> </array> </property> </bean> </beans>

8. 創建測試類

@Test //前置通知
public void  testBefore(){
    ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
    /**
     * 獲取的是代理工廠 返回的是目標對象
     */
    UserDao userDao= context.getBean("userProxy",UserDao.class);
    userDao.eat();
    System.out.println("***********************");
    userDao.sleep();

}
@Test //後置通知
public void  testAfter(){
    ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
    UserDao userDao= context.getBean("userProxy",UserDao.class);
    userDao.eat();
}
@Test //環繞通知
public void  testAround(){
    ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
    UserDao userDao= context.getBean("userProxy",UserDao.class);
   String  result=userDao.eat();
    System.out.println(result);
}
@Test //異常通知
public void  testException(){
    ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
    UserDao userDao= context.getBean("exceptionProxy",UserDao.class);
    try {
        userDao.login("aa","admin");
    }catch (MyException ex){
        ex.printStackTrace();
    }
}

  面對以上案例 發現幾個問題:

    1.每個代理工廠只能給一個目標對象服務!實際開發過程中,不止一個目標對象!

    2.不能實現給 指定的 主業務增強!

    3.測試類getBean的時候還是獲取的代理!應該是service層對象才對!

   以上問題怎麽解決呢?想知道的話,下次再來吧!哈哈~~(先讓我們的大腦旋轉起來吧!)

Spring(九)--通知