8 代理設(shè)計模式

代理模式是主要對我們方法執(zhí)行之前與之后實現(xiàn)增強。
代理模式應(yīng)用場景
1,日志采集
2,權(quán)限控制
3,實現(xiàn)aop
4,mybatis mapper
5,Spring的事務(wù)
6,全局捕獲異常
7,rpc遠程調(diào)用接口(傳遞就是接口)
8,代理數(shù)據(jù)源
9,自定義注解
aop---基于代理實現(xiàn)
代理模式實現(xiàn)的原理
代理模式主要包含三個角色,即抽象主題角色(Subject),委托類角色(被代理角色,Proxied)以及代理類角色(Proxy)
抽象主題角色:可以是接口,也可以是抽象類;
委托類角色: 真實主題角色,業(yè)務(wù)邏輯的具體執(zhí)行者;
代理類角色: 內(nèi)部含有對真實對象RealSubject的引用,負責對真實主題角色的調(diào)用,并在真實主題角色處理前后做預(yù)處理和后處理。
代理模式創(chuàng)建方式:
相關(guān)測試代碼:

package com.taotao.proxy.service;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:23
 */
public interface OrderService {
    /**
     * 追加訂單數(shù)據(jù)
     */
    String addOrder(String orderName);
}


package com.taotao.proxy.service.impl;

import com.taotao.proxy.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:24
 */
@Service("OrderService")
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Override
    public String addOrder(String orderName) {

        log.info("<orderName:{}>", orderName);
        log.info("addOrder方法之后處理");
        return "OK";
    }
}


package com.taotao.proxy.service.proxy;

import com.taotao.proxy.service.OrderService;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:37
 */
@Slf4j
public class OrderServiceProxy implements OrderService {
    //代理類 到底是需要調(diào)用哪一個 被代理類
    private OrderService orderService;

    public OrderServiceProxy(OrderService orderService) {
        this.orderService = orderService;
    }

    @Override
    public String addOrder(String orderName) {
        log.info("<在adder方法之前處理 orderName:{}>", orderName);
        String resultString = orderService.addOrder(orderName);//調(diào)用被代理類
        return resultString;
    }
}

package com.taotao.proxy.service;

import com.taotao.proxy.service.impl.OrderServiceImpl;
import com.taotao.proxy.service.proxy.OrderServiceProxy;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:44
 */
public class Test01 {
    public static void main(String[] args) {
        //被代理類
        OrderServiceProxy orderServiceProxy=new OrderServiceProxy(new OrderServiceImpl());
        String result= orderServiceProxy.addOrder("hello");
        System.out.println(result);
    }
}


package com.taotao.proxy.service;

import com.taotao.proxy.service.proxy1.OrderServiceProxy;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:56
 */
public class Test02 {
    public static void main(String[] args) {
        OrderServiceProxy orderServiceProxy=new OrderServiceProxy();
      String result=  orderServiceProxy.addOrder("oooo");
        System.out.println(result);
    }
}


package com.taotao.proxy.service.proxy1;

import com.taotao.proxy.service.impl.OrderServiceImpl;
import lombok.extern.slf4j.Slf4j;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:51
 */
@Slf4j
public class OrderServiceProxy  extends OrderServiceImpl {
    //讓我們代理類 繼承 代理類

    @Override
    public String addOrder(String orderName) {
        log.info("<在addOrder方法之前處理 orderName:{}>",orderName);
        String result=super.addOrder(orderName);
         //目標方法 執(zhí)行 被代理類
        log.info("<在addOrder方法之后處理 orderName:{}>",orderName);
        return result;
    }
}

動態(tài)代理是在實現(xiàn)階段不用關(guān)心代理類,而是在運行階段才指定哪一個對象。
動態(tài)代理類的源碼是在程序運行期間由JVM根據(jù)反射等機制動態(tài)生成。
jdk動態(tài)代理的一般步驟如下:
1,創(chuàng)建被代理的接口和類
2,實現(xiàn)InvocationHandler接口,對目標接口中聲明的所有方法進行統(tǒng)一處理;
3,調(diào)用Proxy的靜態(tài)方法,創(chuàng)建代理類并生成相應(yīng)的代理對象;
實現(xiàn)原理: 利用攔截器機制必須實現(xiàn)InvocationHandler 接口中的invoke方法實現(xiàn)對我們的目標方法增強

JDK API 動態(tài)代理方法:

package com.taotao.proxy.service;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  22:36
 */
@Slf4j
public class JdkInvocationHandler implements InvocationHandler {
    /**
     * 目標對象
     */
    private Object target;
    public JdkInvocationHandler(Object target){
        this.target=target;
    }
    /**
     *
     * @param proxy jdk自動生成好的代理類
     * @param method 木目標對象的接口
     * @param args 參數(shù)類
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      log.info("<jdk動態(tài)代理目標方法之前>,args:{}",args);
      Object result=method.invoke(target,args);
        log.info("<jdk動態(tài)代理目標方法之后,args:{}", args);
        return result;
    }
    public <T> T getProxy() {
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
}





package com.taotao;

import com.taotao.proxy.service.JdkInvocationHandler;
import com.taotao.proxy.service.OrderService;
import com.taotao.proxy.service.impl.OrderServiceImpl;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-05  22:25
 */
public class Test03 {
    public static void main(String[] args) {
        OrderService orderService=new JdkInvocationHandler(new OrderServiceImpl()).getProxy();
           orderService.addOrder("taotao");
    }
}

動態(tài)代理與靜態(tài)代理的區(qū)別
動態(tài)代理不需要寫代理類對象,通過程序自動生成,而靜態(tài)代理需要我們自己寫代理類對象。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容