多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開源 > php教程 > Java的動(dòng)態(tài)代理機(jī)制及Spring的實(shí)現(xiàn)方式

Java的動(dòng)態(tài)代理機(jī)制及Spring的實(shí)現(xiàn)方式

來(lái)源:程序員人生   發(fā)布時(shí)間:2017-01-23 20:17:39 閱讀次數(shù):2690次

學(xué)習(xí)Java的同學(xué)注意了!!! 
學(xué)習(xí)進(jìn)程中遇到甚么問題或想獲得學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交換群,群號(hào)碼:183993990  我們1起學(xué)Java!


JAVA 代理實(shí)現(xiàn)

代理的實(shí)現(xiàn)分動(dòng)態(tài)代理和靜態(tài)代理,靜態(tài)代理的實(shí)現(xiàn)是對(duì)已生成了的JAVA類進(jìn)行封裝。

動(dòng)態(tài)代理則是在運(yùn)行時(shí)生成了相干代理累,在JAVA中生成動(dòng)態(tài)代理1般有兩種方式。

JDK自帶實(shí)現(xiàn)方法

JDK實(shí)現(xiàn)代理生成,是用類 java.lang.reflect.Proxy, 實(shí)現(xiàn)方式以下

EX:

public class JDKProxy {

      public static Object getPoxyObject(final Object c) {

            return Proxy.newProxyInstance(c.getClass().getClassLoader(), c.getClass().getInterfaces(),// JDK實(shí)現(xiàn)動(dòng)態(tài)代理,但JDK實(shí)現(xiàn)必須需要接口

                        new InvocationHandler() {

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

                                    // TODO Auto-generated method stub

                                    Object reObj = null;

                                    System.out.print("you say: ");

                                    reObj = method.invoke(c, args);

                                    System.out.println(" [" + Calendar.getInstance().get(Calendar.HOUR) + ":"

                                                + Calendar.getInstance().get(Calendar.MINUTE) + " "

                                                + Calendar.getInstance().get(Calendar.SECOND) + "]");

                                    return reObj;

                              }

                        });

      }

}

測(cè)試代理類方法

public class TestForPoxy {

      public static void main(String[] args) {

            ServiceTest service = new ServiceTestImpl();

            System.out.println(service.getClass().getSimpleName());

            ServiceTest poxyService = (ServiceTest) JDKProxy.getPoxyObject(service);

            System.out.println(poxyService.getClass().getSuperclass());

            poxyService.saySomething("hello,My QQ code is 107966750.");

            poxyService.saySomething("what 's your name?");

            poxyService.saySomething("only for test,hehe.");

      }

}

1, Proxy實(shí)現(xiàn)代理的目標(biāo)類必須有實(shí)現(xiàn)接口

2, 生成出來(lái)的代理類為接口實(shí)現(xiàn)類,和目標(biāo)類不能進(jìn)行轉(zhuǎn)換,只能轉(zhuǎn)為接口實(shí)現(xiàn)類進(jìn)行調(diào)用

明顯特點(diǎn):通過此方法生成出來(lái)的類名叫做 $Proxy0

用CGLIB包實(shí)現(xiàn)

CGLIB是1個(gè)開源項(xiàng)目,官方網(wǎng)址是:http://cglib.sourceforge.net/,可以去上面下載最新JAR包,

本項(xiàng)目用的是cglib⑶.0.jar

本項(xiàng)目還加入了依賴JAR包asm⑷.0.jar,asm-util⑷.0.jar

實(shí)現(xiàn)方式以下

EX:

public class CGLIBProxy {

      public static Object getPoxyObject(Object c) {

            Enhancer enhancer = new Enhancer();

            enhancer.setSuperclass(c.getClass());

            enhancer.setCallback(new MethodInterceptor() {

                  public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable {

                        System.out.print("you say: ");

                        proxy.invokeSuper(arg0, arg2);

                        System.out.println(" [" + Calendar.getInstance().get(Calendar.HOUR) + ":"

                                    + Calendar.getInstance().get(Calendar.MINUTE) + " " + Calendar.getInstance().get(Calendar.SECOND)

                                    + "]");

                        return null;

                  }

            });

            return enhancer.create();

      }

}

測(cè)試代理類方法

public class TestForPoxy {

      public static void main(String[] args) {

            ServiceTest service = new ServiceTestImpl();

            System.out.println(service.getClass().getSimpleName());

//          ServiceTest poxyService = (ServiceTest) JDKProxy.getPoxyObject(service);

            ServiceTest poxyService = (ServiceTest) CGLIBProxy.getPoxyObject(service);

            System.out.println(poxyService.getClass().getSuperclass());

            poxyService.saySomething("hello,My QQ code is 107966750.");

            poxyService.saySomething("what 's your name?");

            poxyService.saySomething("only for test,hehe.");

      }

}

 

1, CGLIB實(shí)現(xiàn)方式是對(duì)代理的目標(biāo)類進(jìn)行繼承

2, 生成出了的代理類可以沒方法,生成出來(lái)的類可以直接轉(zhuǎn)換成目標(biāo)類或目標(biāo)類實(shí)現(xiàn)接口的實(shí)現(xiàn)類,因JAVA向上轉(zhuǎn)換

明顯特點(diǎn):通過輸出看出,看誕生成出的代理類的parent類為代理的目標(biāo)類

 

Spring  AOP的代理類機(jī)制分析

 

在spring中,bean都是由動(dòng)態(tài)代理生成出來(lái)的,那末究竟是用JDK的Proxy類實(shí)現(xiàn)呢,還是用CGLIB方式實(shí)現(xiàn)呢。

AOP  Spring需要的依賴JAR包有:

spring-asm⑶.2.0.M1.jar

spring-beans⑶.2.0.M1.jar

spring-context⑶.2.0.M1.jar

spring-core⑶.2.0.M1.jar

spring-expression⑶.2.0.M1.jar

spring-aop⑶.2.0.M1.jar

spring-aspects⑶.2.0.M1.jar

commons\commons-logging⑴.1.1\commons-logging⑴.1.1.jar

aopalliance\aopalliance.jar

lib\aspectjweaver.jar

 

實(shí)現(xiàn)AOP

 

先簡(jiǎn)單的實(shí)現(xiàn)AOP

 

配置以下

 

<?xml version="1.0" encoding="utf⑻"?>

<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⑶.2.xsd

      http://www.springframework.org/schema/aop 

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

      <bean id="test" class="org.ben.spring.service.Test" />

      <bean id="aspectBean" class="org.ben.spring.TestAspect" />

      <!-- 對(duì)Test類進(jìn)行AOP攔截 -->

      <aop:config>

            <aop:aspect id="TestAspect" ref="aspectBean">

                  <!--配置切面-->

                  <aop:pointcut id="businessService"

                        expression="execution(* org.ben.spring.service.Test.say(..))" />

                  <aop:before pointcut-ref="businessService" method="doBefore" />

                  <aop:after pointcut-ref="businessService" method="doAfter" />

            </aop:aspect>

      </aop:config>

</beans>

 

 

然落后行運(yùn)行結(jié)果以下,表示AOP攔截成功

AOP測(cè)試類

public class TestBeans {

      public static void main(String[] args) {

            ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");

            Test test=(Test) ctx.getBean("test");

            System.out.println(test.getClass().getSimpleName());

            test.say();

      }

}

輸出:

do something in befor

welcome for test

do something in after

打印代理類的生成方式

 

第1種情況, Test不實(shí)現(xiàn)任何接口,代碼以下

public class Test {

      public void say() {

            System.out.println("welcome for test,My QQ is 107966750");

      }

}

 

在TestBeans中加入打印當(dāng)前對(duì)象的名稱

以下:

ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");

Test test=(Test) ctx.getBean("test");

System.out.println(test.getClass().getSimpleName());

test.say();

輸出:

Test$$EnhancerByCGLIB$$4791b36c

super class is class org.ben.spring.service.Test

do something in befor

welcome for test

do something in after

 

明顯看到用了AOP以后,輸出的是代理類對(duì)象Test$$EnhancerByCGLIB$$bb9b6a7c.而且它的父類是我們的代理目標(biāo)類。說(shuō)明是有CGLIB生成的

 

 

 

 

 

第2種情況

 

XML的配置不變,改變代理目標(biāo)類Test的實(shí)現(xiàn)方法,以下

public class Test implements TestInter{

      public void say() {

            System.out.println("welcome for test,My QQ is 107966750");

      }

}

和原來(lái)不同的是多繼承了1個(gè)接口,接口中定義了say()方法

在TestBeans中加入打印當(dāng)前對(duì)象的名稱

以下:

ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");

TestInter test=(TestInter) ctx.getBean("test");

System.out.println(test.getClass().getSimpleName());

System.out.println("super class is "+test.getClass().getSuperclass());

test.say();

 

輸出:

$Proxy0

super class is class java.lang.reflect.Proxy

do something in befor

welcome for test,My QQ is 107966750

do something in after

結(jié)論

Spring AOP中,當(dāng)攔截對(duì)象實(shí)現(xiàn)了接口時(shí),生成方式是用JDK的Proxy類。當(dāng)沒有實(shí)現(xiàn)任何接口時(shí)用的是GCLIB開源項(xiàng)陌生成的攔截類的子類.

 附上本文測(cè)試的源碼內(nèi)容  源碼下載

學(xué)習(xí)Java的同學(xué)注意了!!! 
學(xué)習(xí)進(jìn)程中遇到甚么問題或想獲得學(xué)習(xí)資源的話,歡迎加入Java學(xué)習(xí)交換群,群號(hào)碼:183993990  我們1起學(xué)Java!

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 永久免费毛片在线播放 | 亚洲人成网站在线播放942一 | 99久久精品国产高清一区二区 | 欧美一区二区三区视频在线观看 | 久久国产精品久久久 | 欧美激情在线播放一区二区三区 | xxxxx免费| 亚洲综合无码一区二区 | 国产精品一国产精品免费 | 国产精品揄拍100视频最近 | 精品国产91久久久久久久 | 男女啪啪成人免费网站 | 中文字幕一二三区乱码老 | 欧美xxxx性特级高清 | 欧洲美女高清一级毛片 | 国产免费一区二区三区在线 | 亚洲精品456在在线播放 | 91亚洲国产成人精品性色 | 夜夜狠操| 中文字幕乱码人成乱码在线视频 | 日本中文字幕网站 | 国产日产欧美精品一区二区三区 | 羞羞视频免费入口网站 | 欧美精品一区二区三区免费观看 | 亚洲免费视频在线 | 性欧美xxx极品另类 性欧美暴力猛交69hd | 午夜理伦三级播放 | 日韩欧美亚 | 黄色网址免费 | 中文字幕最新中文字幕中文字幕 | 天堂最新在线 | 最近韩国中文字幕更新 | 男人吃奶摸下面69视频免费 | 伊人五月天综合 | 亚洲视频一区二区三区 | 亚洲精品中文字幕乱码三区 | 免费亚洲一区 | 久久精品免费播放 | 高清国产精品久久久久 | 一本大道卡一卡二卡三视频 | 日本欧美视频 |