<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    無線&移動互聯網技術研發

    換位思考·····
    posts - 19, comments - 53, trackbacks - 0, articles - 283
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
    AOP面向切面編程(最突出的是處理權限控制,在本文中,主要介紹日志處理):

    一、由無組件實現AOP引出Spring AOP

    1. 使用JDK中的Proxy技術實現AOP功能

    package cn.itcast.aop;

    import java.lang.reflect.InvocationHandler;

    import java.lang.reflect.Method;

    import java.lang.reflect.Proxy;

    import cn.itcast.service.impl.PersonServiceBean;

    public class JDKProxyFactory implements InvocationHandler{

        
    /**

         *要處理的對象(也就是我們要在方法的前后加上業務邏輯的對象,如例子中的PersonServiceBean)

         
    */


        
    private Object targetObject;

        

        
    /**

         *動態生成目標對象的代理

         *@paramtargetObject

         *
    @return

         
    */


        
    public Object createProxyIntance(Object targetObject){

           
    this.targetObject = targetObject;

           
    return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), 

                  
    this.targetObject.getClass().getInterfaces(), this);

        }


        

        
    /**

         *要處理的對象中的每個方法會被此方法送去JVM調用,也就是說,要處理的對象的方法只能通過此方法調用

         
    */


        @Override

        
    public Object invoke(Object proxy, Method method, Object[] args)

               
    throws Throwable //環繞通知

           PersonServiceBean bean 
    = (PersonServiceBean) this.targetObject;

           Object result 
    = null

           
    if(bean.getUser()!=null){

               
    //.. advice()-->前置通知

               System.out.println(method.getName() 
    + "is called¡¤¡¤¡¤¡¤¡¤¡¤");

               

               
    try {

                  result 
    = method.invoke(targetObject, args);

                  
    // afteradvice() -->后置通知

               }
     catch (RuntimeException e) {

                  
    //exceptionadvice()--> 例外通知

               }
    finally{

                  
    //finallyadvice(); -->最終通知

               }


           }


           
    return result;

        }


    }


     

    2. 使用CGLIB實現AOP功能與AOP概念解釋

    package cn.itcast.aop;

    import java.lang.reflect.Method;

    import cn.itcast.service.impl.PersonServiceBean;

    import net.sf.cglib.proxy.Enhancer;

    import net.sf.cglib.proxy.MethodInterceptor;

    import net.sf.cglib.proxy.MethodProxy;

    /**

     *CGLIB方式實現目標對象的代理

     *CGLIB代理:實現原理類似于JDK動態代理,只是它在運行期間生成的代理對象是針對目標類擴展的子類。CGLIB是高效的代碼生成包,底層是依靠ASM(開源的java字節碼編輯類庫)操作字節碼實現的,性能比JDK強。

     
    */


    publicclass CGlibProxyFactory 
    implements MethodInterceptor{

        
    private Object targetObject;

        
    public Object createProxyIntance(Object targetObject){

           
    this.targetObject = targetObject;

           Enhancer enhancer 
    = new Enhancer();

           enhancer.setSuperclass(
    this.targetObject.getClass());//非final

           enhancer.setCallback(
    this);

           
    return enhancer.create();

        }


        @Override

        
    public Object intercept(Object proxy, Method method, Object[] args,

               MethodProxy methodProxy) 
    throws Throwable {

           PersonServiceBean bean 
    = (PersonServiceBean) this.targetObject;

           Object result 
    = null;

           
    if(bean.getUser()!=null){

               result 
    = methodProxy.invoke(targetObject, args);

           }


           
    return result;

        }


    }


     

       我們省去了業務模塊的代碼,因為這是完全獨立于業務邏輯的,可以單獨由一個完全不懂業務的人管理。測試用例如下:

     

    package junit.test;

    import org.junit.BeforeClass;

    import org.junit.Test;

    import cn.itcast.aop.CGlibProxyFactory;

    import cn.itcast.aop.JDKProxyFactory;

    import cn.itcast.service.PersonService;

    import cn.itcast.service.impl.PersonServiceBean;

    public class AOPTest {

        @BeforeClass

        
    public static void setUpBeforeClass() throws Exception {

        }


        @Test 
    public void proxyTest(){

           JDKProxyFactory factory 
    = new JDKProxyFactory();

           PersonService service 
    = (PersonService) factory.createProxyIntance(new PersonServiceBean("xxx"));

           service.save(
    "888");

        }


        

        @Test 
    public void proxyTest2(){

           CGlibProxyFactory factory 
    = new CGlibProxyFactory();

           PersonServiceBean service 
    = (PersonServiceBean) factory.createProxyIntance(new PersonServiceBean("xxx"));

           service.save(
    "999");

        }


    }

     

    小結:在Spring中,突出的就是業務邏輯的處理,AOP則是建立在業務邏輯處理的切面上,所以可以通過建立模塊、業務層面的切面來對業務邏輯方法進行追蹤


    二、Spring提供了兩種切面使用方式:

    1. 基于xml配置方式進行AOP開發  (鄙人喜歡注解方式,xml配置方式暫不做研究O(∩_∩)O~

    2. 基于注解方式進行AOP開發 

    定義切面

     

    package cn.itcast.service;

    import org.aspectj.lang.ProceedingJoinPoint;

    import org.aspectj.lang.annotation.After;

    import org.aspectj.lang.annotation.AfterReturning;

    import org.aspectj.lang.annotation.AfterThrowing;

    import org.aspectj.lang.annotation.Around;

    import org.aspectj.lang.annotation.Aspect;

    import org.aspectj.lang.annotation.Before;

    import org.aspectj.lang.annotation.Pointcut;

    /**

     *注解方式定義切面

     
    */


    @Aspect

    publicclass MyInterceptor 
    {

        

        @SuppressWarnings(
    "unused")

        @Pointcut(
    "execution (* cn.itcast.service.impl.PersonServiceBean.*(..))")

        privatevoid anyMethod() 
    {}//聲明一個切入點

        

        @Before(
    "anyMethod() && args(name)")

        publicvoid doAccessCheck(String name) 
    {

           System.out.println(
    "前置通知:"+ name);

        }


        

        @AfterReturning(pointcut
    ="anyMethod()",returning="result")

        publicvoid doAfterReturning(String result) 
    {

           System.out.println(
    "后置通知:"+ result);

        }


        

        @After(
    "anyMethod()")

        publicvoid doAfter() 
    {

           System.out.println(
    "最終通知");

        }


        

        @AfterThrowing(pointcut
    ="anyMethod()",throwing="e")

        publicvoid doAfterThrowing(Exception e) 
    {

           System.out.println(
    "例外通知:"+ e);

        }


        

        @Around(
    "anyMethod()")

        
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {

           
    //if(){//判斷用戶是否在權限

           System.out.println(
    "進入方法");

           Object result 
    = pjp.proceed();

           System.out.println(
    "退出方法");

           
    //}

           
    return result;

        }
      

    }


    利用Spring AOP必須的組件包:

     

    spring-framework-2.5.6"lib"cglib"cglib-nodep-2.1_3.jar

    spring-framework-2.5.6
    "lib"aspectj"aspectjweaver.jar

    spring-framework-
    2.5.6"lib"aspectj"aspectjrt.jar

    spring-framework-2.5.6
    "lib"j2ee"common-annotations.jar

    spring-framework-
    2.5.6"lib"jakarta-commons"commons-logging.jar

    spring-framework-2.5.6
    "dist"spring.jar

     

    Spring 配置:

     

    <?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:context="http://www.springframework.org/schema/context"

        xmlns:aop
    ="http://www.springframework.org/schema/aop"

        xsi:schemaLocation
    ="http://www.springframework.org/schema/beans

               http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd

               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
    >

        
    <aop:aspectj-autoproxy />

        
    <bean id="myInterceptor" class="cn.itcast.service.MyInterceptor" />

        
    <bean id="personService" class="cn.itcast.service.impl.PersonServiceBean"></bean>

    </beans>

     

    測試用例:

     

    package junit.test;

    import org.junit.BeforeClass;

    import org.junit.Test;

    import org.springframework.context.ApplicationContext;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import cn.itcast.service.PersonService;

    publicclass SpringAOPTest 
    {

        @BeforeClass

        publicstaticvoid setUpBeforeClass() 
    throws Exception {

        }


        @Test

        publicvoid interceptorTest() 
    {

           ApplicationContext cxt 
    = new ClassPathXmlApplicationContext("beans.xml");

           PersonService personService 
    = (PersonService) cxt.getBean("personService");

           personService.save(
    "xx");

        }


    }

     


    三、AOP術語:

    Aspect(切面):指橫切面關注點的抽象即為切面,它與類相似,只是兩者的關注點不一樣,類是對物體特征的抽象,而切面是橫切性關注點的抽象

    Joinpoint(連接點):所謂連接點是指那些被攔截到的點。在Spring中,這些點指的是方法,因為spring只支持方法類型的連接點,實際上joinpoint還可以是field或類構造器

    Pointcut(切入點):所謂的切入點是指我們要對那些joinpoint進行攔截的定義

    Advice(通知):所謂的通知是指攔截到joinpoint之后所要做的事情就是通知。通知分為前置通知,后置通知,異常通知,最終通知,環繞通知

    Target(目標對象):代理的目標對象

    Weave(織入):指將aspects應用到target對象并且導致proxy對象創建的過程稱為織入

    Introduction(引入):在不修改類代碼的前提下,introduction可以在運行期為類動態的添加一些方法或field

    主站蜘蛛池模板: 亚洲欧美成人av在线观看| 久久亚洲精品成人777大小说| 国内精品久久久久影院免费 | 国产精品亚洲四区在线观看| 2022久久国产精品免费热麻豆| 四虎影院免费在线播放| 亚洲精品国产免费| 日本人的色道免费网站| 亚洲麻豆精品果冻传媒| 精品久久8x国产免费观看| 亚洲AV无码乱码在线观看代蜜桃| 日本一区二区三区免费高清| 久久亚洲精品无码观看不卡| 国产精品永久免费| 亚洲愉拍99热成人精品热久久| 中国精品一级毛片免费播放| 亚洲av丰满熟妇在线播放| 日韩免费无码视频一区二区三区| 91在线亚洲精品专区| av免费不卡国产观看| 亚洲成在人线aⅴ免费毛片| 亚洲?v无码国产在丝袜线观看| 一级毛片免费不卡| 亚洲V无码一区二区三区四区观看| 久久精品国产大片免费观看| 亚洲国产精品xo在线观看| 中文字幕无码不卡免费视频| 亚洲国产AV无码一区二区三区| 亚洲国模精品一区| 野花香高清视频在线观看免费| 亚洲国产成人私人影院| 日韩一区二区a片免费观看 | 在线观看人成视频免费| 菠萝菠萝蜜在线免费视频| 男人的好看免费观看在线视频| 精品国产亚洲AV麻豆| 啦啦啦www免费视频| 一级黄色免费大片| 久久久久亚洲AV成人无码| 成人免费a级毛片无码网站入口| 亚洲自偷自偷精品|