8 代理设计模式

代理模式是主要对我们方法执行之前与之后实现增强。
代理模式应用场景
1,日志采集
2,权限控制
3,实现aop
4,mybatis mapper
5,Spring的事务
6,全局捕获异常
7,rpc远程调用接口(传递就是接口)
8,代理数据源
9,自定义注解
aop---基于代理实现
代理模式实现的原理
代理模式主要包含三个角色,即抽象主题角色(Subject),委托类角色(被代理角色,Proxied)以及代理类角色(Proxy)
抽象主题角色:可以是接口,也可以是抽象类;
委托类角色: 真实主题角色,业务逻辑的具体执行者;
代理类角色: 内部含有对真实对象RealSubject的引用,负责对真实主题角色的调用,并在真实主题角色处理前后做预处理和后处理。
代理模式创建方式:
相关测试代码:

package com.taotao.proxy.service;

/**
 * @Author: wangjin
 * @CreateTime: 2022-07-03  21:23
 */
public interface OrderService {
    /**
     * 追加订单数据
     */
    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 {
    //代理类 到底是需要调用哪一个 被代理类
    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);//调用被代理类
        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);
         //目标方法 执行 被代理类
        log.info("<在addOrder方法之后处理 orderName:{}>",orderName);
        return result;
    }
}

动态代理是在实现阶段不用关心代理类,而是在运行阶段才指定哪一个对象。
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态生成。
jdk动态代理的一般步骤如下:
1,创建被代理的接口和类
2,实现InvocationHandler接口,对目标接口中声明的所有方法进行统一处理;
3,调用Proxy的静态方法,创建代理类并生成相应的代理对象;
实现原理: 利用拦截器机制必须实现InvocationHandler 接口中的invoke方法实现对我们的目标方法增强

JDK API 动态代理方法:

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 参数类
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      log.info("<jdk动态代理目标方法之前>,args:{}",args);
      Object result=method.invoke(target,args);
        log.info("<jdk动态代理目标方法之后,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");
    }
}

动态代理与静态代理的区别
动态代理不需要写代理类对象,通过程序自动生成,而静态代理需要我们自己写代理类对象。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容