代理设计模式

代理设计模式

代理设计模式分为:

  • 静态代理设计模式
  • 动态代理设计模式

代理的核心功能是方法增强

一、静态代理

静态代理角色分析

  • 抽象角色:使用接口或者抽象类实现
  • 真实角色:被代理的角色
  • 代理角色:代理正式角色,代理真实角色后可以做一些附属的操作
  • 客户:使用代理角色进行操作

写一个接口

package com.assin;

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:22
 */
public interface Singer {
    /**
     * 唱歌
     */
     void sing();
}

定义男歌手

package com.assin;

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:23
 */
public class MaleSinger implements Singer{
    @Override
    public void sing() {
        System.out.println("男歌手唱歌");
    }
}

定义经纪人

package com.assin;

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:22
 */
public class Agent implements Singer{

    private Singer singer;

    public Agent(Singer singer) {
        this.singer = singer;
    }

    @Override
    public void sing() {

        System.out.println("协商费用");


        singer.sing();


        System.out.println("结算费用");

    }
}

Client . java 即客户

package com.assin;

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:24
 */
public class Client {


    public static void main(String[] args) {

        Singer singer = new MaleSinger();

        Agent agent = new Agent(singer);

        agent.sing();


    }
}

客户可以直接接触的是agent,agent在singer演出时完成除开唱歌的其它工作。

还可以使用继承类的方式

优点

  • 没有必要为了一下前置后置工作改变singer这个类
  • 公共的统一问题交给代理处理
  • 公共业务进行扩展或变更时,可以更加方便

这不就是更加符合开闭原则,单一原则吗?

缺点 :

  • 每个类都写个代理,麻烦死了。

二、动态代理

  • 动态代理的角色和静态代理的一样
  • 动态代理使用代码动态自动生成代理代码,静态代理则是我们自己手动写出代理代码
  • 动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
    • 基于接口的动态代理----JDK动态代理
    • 基于类的动态代理–cglib

动态代理就是当有大量的类需要执行一些共同代码时,我们自己写太麻烦,那能不能直接使用java代码,自动生成一个类帮助我们批量的增强某些方法

1、JDK原生的动态代理

JDK****的动态代理需要了解两个类

核心 : InvocationHandler 和 Proxy , 打开JDK帮助文档看看

【InvocationHandler:调用处理程序】

Object invoke(Object proxy, 方法 method, Object[] args)//参数 
 //proxy - 调用该方法的代理实例 
 //method -所述方法对应于调用代理实例上的接口方法的实例。方法对象的声明类将是该方法声明的接 口,它可以是代理类继承该方法的代理接口的超级接口。
 //args -包含的方法调用传递代理实例的参数值的对象的阵列,或null如果接口方法没有参数。原始类 型的参数包含在适当的原始包装器类的实例中,例如java.lang.Integer或java.lang.Boolean 。

【Proxy : 代理】

Proxy.newProxyInstance(ClassLoader loader,
                       Class<?>[] interfaces, 
                       InvocationHandler h) 

Agent 代理人

package com.assin;

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

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:22
 */
public class Agent implements InvocationHandler {

    private Object object;

    public Agent(Object object) {
        this.object = object;
    }

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

        System.out.println("开启");
        Object invoke = method.invoke(object,args);
        System.out.println("提交");

        return invoke;

    }
}

Client 客户

package com.assin;

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

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:24
 */
public class Client {


    public static void main(String[] args) {

        Singer maleSinger = new MaleSinger();


        Singer singer = (Singer)Proxy.newProxyInstance(Client.class.getClassLoader(),
                new Class[]{Singer.class}, new Agent(maleSinger));

        //  Agent agent = new Agent(singer);

       singer.sing();


    }
}

核心:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口!、

2、基于cglib


    <dependencies>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.3.0</version>

        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>

                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <target>14</target>
                    <source>14</source>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
package com.assin;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

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

/**
 * @Author:ASSIN
 * @Date: 2021/8/31 23:24
 */
public class Client2 {


    public static void main(String[] args) {

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(MaleSinger2.class);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("------");
                Object invoke = methodProxy.invokeSuper(o, objects);
                System.out.println("++++++");
                return invoke;
            }
        });

        MaleSinger2 maleSinger2 = (MaleSinger2) enhancer.create();
        maleSinger2.sing();


    }
}

  1. Java动态代理只能够对接口进行代理,不能对普通的类进行代理(因为所有生成的代理类的父类为

Proxy,Java类继承机制不允许多重继承);

  1. cglib能够代理普通类;

  2. Java动态代理使用Java原生的反射API进行操作,在生成类上比较高效;cglib使用ASM框架直接对字节码(.class 二进制文件)进行操作,在类的执行过程中比较高效

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值