JDK動(dòng)態(tài)代理

今天呢。我們來學(xué)習(xí)意向JDK的動(dòng)態(tài)代理
也可以使用JDK的API實(shí)現(xiàn)動(dòng)態(tài)代理。這種方式要求目標(biāo)類有一個(gè)接口。這種方式也叫做JDK代理或接口代理。

1、代理類

使用前面靜態(tài)代理一節(jié)的 UserService 和 UserServiceImpl

2、創(chuàng)建代理工廠

package com.qfedu.proxy.utils;
public class ProxyFactoryJDK {

    /**
     * 目標(biāo)對(duì)象
     */
    private Object target;

    public ProxyFactoryJDK(Object target) {
        this.target = target;
    }

    //給目標(biāo)對(duì)象生成代理對(duì)象
    public Object getProxyInstance() {

        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//指定當(dāng)前目標(biāo)對(duì)象使用類加載器
                target.getClass().getInterfaces(),//目標(biāo)對(duì)象的接口類型

                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("前置通知。。。。。。");
                        //執(zhí)行目標(biāo)對(duì)象方法
                        Object returnValue = method.invoke(target, args);
                        System.out.println("后置通知。。。。。。");
                        return returnValue;
                    }
                }
        );
    }
}

JDK實(shí)現(xiàn)代理只需要使用newProxyInstance方法,此方法需要三個(gè)參數(shù)
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
這個(gè)方法是靜態(tài)方法,參數(shù)分別為:
ClassLoader loader 指定當(dāng)前目標(biāo)對(duì)象使用類加載器
Class<?>[] interfaces 目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類型
InvocationHandler h 事件處理器,執(zhí)行目標(biāo)對(duì)象的方法時(shí),會(huì)觸發(fā)事件處理器的方法,會(huì)把當(dāng)前執(zhí)行目標(biāo)對(duì)象的方法作為參數(shù)傳入

3、測(cè)試

/**

  • 測(cè)試JDK動(dòng)態(tài)代理
    */
@Test
public void test03(){

    //創(chuàng)建目標(biāo)對(duì)象
    UserService userService = new UserServiceImpl();
    //創(chuàng)建代理工廠
    ProxyFactoryJDK proxyFactory = new ProxyFactoryJDK(userService);
    //從代理工廠或得動(dòng)態(tài)代理類
    UserService userService1Proxy = (UserService)proxyFactory.getProxyInstance();
    //調(diào)用代理的代理方法
    userService1Proxy.save();
}

總結(jié):

如果目標(biāo)對(duì)象有接口,用JDK代理
如果目標(biāo)對(duì)象沒有接口,用Cglib代理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容