IOC和AOP使用擴展之AOP詳解實現類


摘要:

 
“Depend on yourself” is what nature says to every man.  Parents can help you. Teachers can help you. others still can help you. But all these only help you to help yourself

  “自立”是自然對每個人的要求.也許你的父母、老師能夠幫助你,其他人也可以幫助你,但是所有這些人都只是幫你更加自主、自立。

 

最近完結了有關於AOP相關知識的學習,接下來就給大家講講我對AOP的一些見解。

 

既然學習AOP大家知道AOP是什么嘛?那么就開始嘍~

 

AOP(Aspect Oriented Programming):面向切面編程,也是一種變成思想。(靜態角度)

OOP(Object Oriented Programming):面向對象編程。(動態代理:JDK動態代理    CGLIB動態代理)

代理模(Proxy):為其他對象提供一個代理以控制對這個對象的訪問。

適合的場合:遠程代理  虛擬代理  安全代理(只需要簡單了解不做詳解)

                                                      ↑   ↑   ↑   ↑   ↑   ↑只是關於代理的圖片展示稍后會有詳細代碼

 

基本術語(一些名詞): 

 

(1)切面(Aspect)
切面泛指[*交叉業務邏輯*]。事務處理和日志處理可以理解為切面。常用的切面有通知(Advice)與顧問(Advisor)。實際就是對主業務邏輯的一種增強。

 

(2)織入(Weaving)
織入是指將切面代碼插入到目標對象的過程。代理的invoke方法完成的工作,可以稱為織入。

 

(3) 連接點(JoinPoint) 
連接點是指可以被切面織入的方法。通常業務接口的方法均為連接點

 

(4)切入點(PointCut)
切入點指切面具體織入的方法
注意:被標記為final的方法是不能作為連接點與切入點的。因為最終的是不能被修改的,不能被增強的。

 

(5)目標對象(Target)
目標對象指將要被增強的對象。即包含主業務邏輯的類的對象。

(6)通知(Advice) 
通知是切面的一種實現,可以完成簡單的織入功能。通知定義了增強代碼切入到目標代碼的時間點,是目標方法執行之前執行,還是執行之后執行等。切入點定義切入的位置,通知定義切入的時間。

 

(7)顧問(Advisor)
顧問是切面的另一種實現,能夠將通知以更為復雜的方式織入到目標對象中,是將通知包裝為更復雜切面的裝配器。

 

Spring的經典AOP配置方案

  1、使用的是Aspectj第三方框架,實現了AOP思想

  2、注解配置的AOP

  3、純POJO  就是一個普通的類<aop:config>

 

接下來進入代碼模式:

代碼模式一:純POJO(通過POJO來實現一個前置增強類)

 

定義一個簡單的UserBiz類給它一個方法:

1 package cn.happy.biz;
2 
3 public class UserBiz {
4    public void addStu(UserInf user){
5        System.out.println("add  ok");
6    }
7 }

 

在aop包下BeforeAdvice前置增強類,它需要實現MethodBeforeAdvice接口的before方法:

 1 import org.springframework.aop.MethodBeforeAdvice;
 2 
 3 /**
 4  * before
 5  *
 6  */
 7 public class BeforeAdvice implements MethodBeforeAdvice{
 8 
 9     /**
10      * 
11      * @param method 被代理的目標的方法
12      * @param args  傳遞給目標方法的參數
13      * @param obj    被代理的目標對象
14  
15      * @throws Throwable
16      */
17     @Override
18     public void before(Method method, Object[] args , Object obj)
19             throws Throwable {
20         System.out.println("========before======");
21     }

 

 

配置文件(注意引入的命名空間)<aop:config>配置下實現切面:

 1 ......
 2   <bean id="biz" class="cn.happy.biz.UserBiz"></bean>
 3    
 4    <!-- 前置 -->
 5    <bean id="beforeAdvice" class="cn.happy.aop.BeforeAdvice"></bean>
 6    <!-- aop配置切面 -->
 7    <aop:config>
 8    <!-- 定義切點 -->
 9    <aop:pointcut expression="execution(public void *(cn.happy.biz.UserInf))"      id="pointcut"/>
10    <!-- 增強處理和切點結合 -->
11    <aop:advisor advice-ref="beforeAdvice" pointcut-ref="pointcut"/>
12    <aop:advisor advice-ref="afterAdivice" pointcut-ref="pointcut"/>
13    </aop:config>
14 ......

 

測試類:

1  public void testOne(){
2         ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
3         UserBiz biz = (UserBiz)ctx.getBean("biz");
4         biz.addStu(new UserInf());
5         
6     }

 

=========================華麗的分割線==================================

用注解配置的AOP:前置通知,后置通知,返回通知,異常通知,環繞通知

定義一個接口:

1 public interface ISomeService {
2     //1.1  執行事務
3    public void doTransaction();
4     //1.2 書寫日志
5    public String doLog();
6 }

 

實現接口的實現類:

 1 public class SomeServiceImpl implements ISomeService {
 2 
 3     public void doTransaction() {
 4         System.out.println("開啟事務");
 5     }
 6 
 7     public String doLog() {
 8         System.out.println("書寫日志"+5/0);
 9         return "我是書寫日志的返回值哦!!!!!";
10     }
11 
12 }

 

增強類用注解寫:

 1 @Aspect  2 public class MyAspect {
 3     //前置通知
 4     @Before(value="execution(public * *(..))")  5     public void MyBefore(){
 6         System.out.println("這是前置通知哦!!!!!!!在執行目標對象之前執行");
 7     }
 8     
 9     //后置通知
10     @AfterReturning(value="execution(public * *(..))") 11     public void MyAfterReturning(){
12         System.out.println("這是后置通知哦!!!!!!!在執行目標對象之前執行");
13     }
14     
15     //環繞通知
16 /* @Around(value="execution(public * *(..))") 17     public void MyAround(ProceedingJoinPoint pjp){
18         System.out.println("這是環繞通知前哦!!!!!!!在執行目標對象之前執行");
19         try {
20             pjp.proceed();
21             System.out.println("這是環繞通知后哦!!!!!!!在執行目標對象之前執行");
22         } catch (Throwable e) {
23             // TODO Auto-generated catch block
24             e.printStackTrace();
25         }
26     }*/
27     
28     //異常通知
29     @AfterThrowing(value="execution(public * *(..))") 30     public void MyAfterThrowing(){
31         System.out.println("這是異常通知哦!!!!!!!在執行目標對象之前執行");
32     }
33     
34     //最終通知
35     @After(value="execution(public * *(..))") 36     public void MyAfter(){
37         System.out.println("這是最終通知哦!!!!!!!在執行目標對象之前執行");
38     }
39 }

 

 

配置文件:

1 <!-- 目標對象 -->
2    <bean id="someService" class="cn.happy.enetity.SomeServiceImpl"></bean>
3 
4    <!-- 切面: -->
5    <bean id="myAspect" class="cn.happy.aspece.MyAspect"></bean>
6    <!--aop:aspectj可以啟動對@AspectJ注解支持-->
7    <aop:aspectj-autoproxy/>
8 </beans>

 

測試類:

1 public void testOne(){
2         
3         ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
4         ISomeService service = (ISomeService)ctx.getBean("someService");
5         service.doTransaction();
6         String result = service.doLog();
7         System.out.println(result);
8     }

 

=========================華麗的分割線==================================

使用的是Aspectj第三方框架,實現了AOP思想XML的方式(就是一個普通類通過配置實現 )

定義一個接口:

1 public interface ISomeService {
2     //1.1  執行事務
3    public void doTransaction();
4     //1.2 書寫日志
5    public String doLog();
6 }

  

實現類:

 1 public class SomeServiceImpl implements ISomeService {
 2 
 3     public void doTransaction() {
 4         System.out.println("開啟事務");
 5     }
 6 
 7     public String doLog() {
 8         /*System.out.println("書寫日志"+5/0);*/
 9         System.out.println("書寫日志");
10         return "我是書寫日志的返回值哦!!!!!";
11     }
12 
13 }

 

定一個增強類就是一個普通類通過配置實現 :

 1 public class MyAspect {
 2     // 前置通知execution(public * *(..))
 3     public void MyBefore() {
 4         System.out.println("這是前置通知哦!!!!!!!在執行目標對象之前執行");
 5     }
 6 
 7     // 后置通知execution(public * *(..))
 8     public void MyAfterReturning() {
 9         System.out.println("這是后置通知哦!!!!!!!在執行目標對象之前執行");
10     }
11 
12     // 異常通知
13     public void MyAfterThrowing() {
14         System.out.println("這是異常通知哦!!!!!!!在執行目標對象之前執行");
15     }
16 
17     // 最終通知
18     public void MyAfter() {
19         System.out.println("這是最終通知哦!!!!!!!在執行目標對象之前執行");
20     }
21     
22     //環繞通知
23     public String MyAround(ProceedingJoinPoint pjp){
24         System.out.println("這是環繞通知前哦!!!!!!!在執行目標對象之前執行");
25         try {
26             Object result=pjp.proceed();
27             System.out.println("這是環繞通知后哦!!!!!!!在執行目標對象之前執行");
28         } catch (Throwable e) {
29             // TODO Auto-generated catch block
30             e.printStackTrace();
31         }
32         return "result";
33     }
34 }

 

 配置文件:

 1 ......
 2  <!-- 目標對象 -->
 3    <bean id="someService" class="enetity.SomeServiceImpl"></bean>
 4 
 5    <!-- 切面: -->
 6    <bean id="myAspect" class="aspece.MyAspect"></bean>
 7   
 8   
 9   <!--  aop的配置 -->
10   <aop:config>
11   <!-- 切點 -->
12   <aop:pointcut expression="execution(public * *(..))" id="dopointcut"/>
13       <aop:aspect ref="myAspect">
14   
15           <aop:before method="MyBefore" pointcut-ref="dopointcut"/>
16           <aop:after-returning method="MyAfterReturning" pointcut-ref="dopointcut"/>
17           <!-- <aop:after-throwing method="MyAfterThrowing" pointcut-ref="dopointcut"/> -->
18           <aop:after method="MyAfter" pointcut-ref="dopointcut"/>
19           <aop:around method="MyAround" pointcut-ref="dopointcut"/>
20       </aop:aspect>
21   
22   </aop:config>
23 </beans>
24 ......

 

測試類:

1   public void testOne(){
2         
3         ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
4         ISomeService service = (ISomeService)ctx.getBean("someService");
5         service.doTransaction();
6         String result = service.doLog();
7         System.out.println(result);
8     }

 

 

以上就是我對AOP相關知識代碼層面的講解。學的不是很好,也是早上請教了同學才能更深一層了解AOP。就如文章開頭:

  “自立”是自然對每個人的要求.也許你的父母、老師能夠幫助你,其他人也可以幫助你,但是所有這些人都只是幫你更加自主、自立。

希望可以鼓勵那些在快學不下去的時候去請教下同學,老師...

  

 

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM