11 结构型模式- 代理模式

这篇具有很好参考价值的文章主要介绍了11 结构型模式- 代理模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

结构性模式一共包括七种:

代理模式、桥接模式、装饰者模式、适配器模式、门面(外观)模式、组合模式、和享元模式。
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

1 代理模式介绍

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
软件开发中的代理
代理模式中引入了一个新的代理对象,代理对象在客户端对象和目标对象之间起到了中介的作用,它去掉客户不能看到的内容和服务或者增加客户需要的额外的新服务.

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

2 代理模式原理

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

3 静态代理实现

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

举例:保存用户功能的静态代理实现
public interface IUserDao {

    void save();
}
/**
 * 目标类
 **/
public class UserDaoImpl implements IUserDao {

    @Override
    public void save() {
        System.out.println("保存数据");
    }
}
/**
 * 代理类
 **/
public class UserDaoProxy implements IUserDao {

    private IUserDao target;

    public UserDaoProxy(IUserDao target) {
        this.target = target;
    }

    @Override
    public void save() {
        System.out.println("开启事务"); //扩展额外的功能
        target.save();
        System.out.println("提交事务");
    }
}
/**
     * 静态代理
     *     优点: 可以在不修改目标类的前提下,扩展目标类的功能
     *     缺点:
     *        1.冗余.由于代理对象要实现和目标对象一致的接口,会产生很多的代理.
     *        2.不易维护.一旦接口中增加方法,目标对象和代理对象都要进行修改.
     */
    @Test
    public void testStaticProxy(){

        //目标类
        IUserDao dao = new UserDaoImpl();

        //代理对象
        UserDaoProxy proxy = new UserDaoProxy(dao);
        proxy.save();
    }
4 JDK动态代理

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

举例:保存用户功能的静态代理实现

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

/**
 * 代理工厂类-动态的生成代理对象
 **/
public class ProxyFactory {

    //维护一个目标对象
    private Object target;

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

    //为目标对象生成代理对象
    public Object getProxyInstance(){

        return Proxy.newProxyInstance(
                //目标类使用的类加载器
                target.getClass().getClassLoader(),
                //目标对象实现的接口类型
                target.getClass().getInterfaces(),
                new InvocationHandler() { //事件处理器

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

                        System.out.println("开启事务");
                        method.invoke(target,args);
                        System.out.println("提交事务");
                        return null;
                    }
                }
        );
    }
}

测试:

public static void main(String[] args) {

        IUserDao userDao = new UserDaoImpl();
        System.out.println(userDao.getClass()); //目标对象的信息

        IUserDao proxy = (IUserDao) new ProxyFactory(userDao).getProxyInstance();//获取代理对象
        System.out.println(proxy.getClass());
        proxy.save();//代理方法

        while (true){}
    }
5 类是如何动态生成的

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

6代理类的调用过程

我们通过借用阿里巴巴的一款线上监控诊断产品 Arthas(阿尔萨斯) ,对动态生成的代理类代码进行查看.
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
代理类代码如下:

package com.sun.proxy;

import com.mashibing.proxy.example01.IUserDao;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements IUserDao {
	
	private static Method m1;
	private static Method m3;
	private static Method m2;
	private static Method m0;
	
	public $Proxy0(InvocationHandler invocationHandler) {
		super(invocationHandler);
	}

	static {
		try {	
			m1 = Class.forName("java.lang.Object").getMethod("equals",Class.forName("java.lang.Object"));
			m3 = Class.forName("com.mashibing.proxy.example01.IUserDao").getMethod("save", new Class[0]);
			m2 = Class.forName("java.lang.Object").getMethod("toString", newClass[0]);
			m0 = Class.forName("java.lang.Object").getMethod("hashCode", newClass[0]);
			return;
		}catch (NoSuchMethodException noSuchMethodException) {
			throw new NoSuchMethodError(noSuchMethodException.getMessage());
		}catch (ClassNotFoundException classNotFoundException){
			throw new NoClassDefFoundError(classNotFoundException.getMessage());
		}
	}

	public final boolean equals(Object object) {
		try {
			return (Boolean)this.h.invoke(this, m1, newObject[]{object});
		}catch (Error | RuntimeException throwable) {
			throw throwable;
		}catch (Throwable throwable) {
			throw new UndeclaredThrowableException(throwable);
		}
	}

	public final String toString() {
		try {
			return (String)this.h.invoke(this, m2, null);
		}catch (Error | RuntimeException throwable) {
			throw throwable;
		}catch (Throwable throwable) {
			throw new UndeclaredThrowableException(throwable);
		}
	}

	public final int hashCode() {
		try {
			return (Integer)this.h.invoke(this, m0, null);
		}catch (Error | RuntimeException throwable) {
			throw throwable;
		}catch (Throwable throwable) {
			throw new UndeclaredThrowableException(throwable);
		}
	}

	public final void save() {
		try {
			this.h.invoke(this, m3, null);
			return;
		}catch (Error | RuntimeException throwable) {
			throw throwable;
		}catch (Throwable throwable) {
			throw new UndeclaredThrowableException(throwable);
		}
	}
}

爲了方便理解简化后的代码:

package com.sun.proxy;

import com.mashibing.proxy.example01.IUserDao;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements IUserDao {
	
	private static Method m3;
	
	public $Proxy0(InvocationHandler invocationHandler) {
		super(invocationHandler);
	}

	static {
		try {
			m3 = Class.forName("com.mashibing.proxy.example01.IUserDao").getMethod("save", new Class[0]);
			return;
		}
	}

	public final void save() {
		try {
			this.h.invoke(this, m3, null);
			return;
		}
	}
}

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

7 cglib动态代理

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
使用cglib 需要引入cglib 的jar包,如果你已经有spring-core的jar包,则无需引入,因为spring中包含了cglib 。

<dependency>
	<groupId>cglib</groupId>
	<artifactId>cglib</artifactId>
	<version>3.2.5</version>
</dependency>

示例代码
目标类:

/**
 * 目标类
 **/
public class UserServiceImpl {
    //查询功能
    public List<User>  findUserList(){
        return Collections.singletonList(new User("tom",23));
    }
}

cglib代理类,需要实现MethodInterceptor接口,并指定代理目标类target

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.text.SimpleDateFormat;
import java.util.Calendar;
//在實現動態代理的同時擴展一個日志的功能
public class UserLogProxy implements MethodInterceptor {
    /**
     * 生成CGLIB动态代理类方法
     * @param target    需要被代理的目标类
     * @return: java.lang.Object  代理类对象
     */
    public Object getLogProxy(Object target){

        //增强器类,用来创建动态代理类
        Enhancer enhancer = new Enhancer();

        //设置代理类的父类字节码对象
        enhancer.setSuperclass(target.getClass());

        //设置回调
        enhancer.setCallback(this);

        //创建动态代理对象,并返回
        return enhancer.create();
    }

    /**
     * 实现回调方法
     * @param o      代理对象
     * @param method  目标对象中的方法的Method实例
     * @param args      实际参数
     * @param methodProxy  代理类对象中的方法的Method实例
     * @return: java.lang.Object
     */
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        Calendar instance = Calendar.getInstance();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.println(format.format(instance.getTime()) + "[ " +method.getName() +"] 查询用户信息...");
        Object result = methodProxy.invokeSuper(o, args);
        return null;
    }
}

public class User {

    private String name;

    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
8 cglib代理流程

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节

9代理模式总结

11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
11 结构型模式- 代理模式,设计模式,java,代理模式,1024程序员节
參考文章:文章来源地址https://www.toymoban.com/news/detail-721128.html

https://www.cnblogs.com/hg-blogs/p/17314887.html

到了这里,关于11 结构型模式- 代理模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java 设计模式】结构型之代理模式

    代理模式(Proxy Pattern)是一种结构型设计模式, 它允许通过一个代理对象控制对其他对象的访问 。代理模式在访问对象时引入了一定程度的间接性,使得可以在访问对象前后进行一些额外的操作。在本文中,我们将深入研究Java中代理模式的定义、结构、使用场景以及如何在

    2024年01月21日
    浏览(48)
  • 笨蛋学设计模式结构型模式-桥接模式【11】

    7.5.1概念 ​ 桥接模式主要将抽象部分与实现部分分离开来,使得它们可以相互独立地变化。抽象部分定义了一个抽象类或接口,包含一些基本操作以及包含一个指向实现部分的引用。实现部分也是一个抽象类或接口,定义了一些具体的操作。 7.5.2场景 ​ 比如在路上随处可见

    2024年01月17日
    浏览(45)
  • 【设计模式】第11节:结构型模式之“装饰器模式”

    装饰器模式主要解决继承关系过于复杂的问题,通过组合来替代继承。它主要的作用是给原始类添加增强功能。这也是判断是否该用装饰器模式的一个重要的依据。除此之外,装饰器模式还有一个特点,那就是可以对原始类嵌套使用多个装饰器。为了满足这个应用场景,在设

    2024年02月06日
    浏览(45)
  • 设计模式-04.01-结构型-代理&桥接&装饰器&适配器

    创建型模式比较好理解,后面的结构型和行为型设计模式不是那么好理解。如果遇到不好理解的设计模式,我一般会在开头举比较简单的Demo案例来帮助理解。 前面几节,我们讲了设计模式中的创建型模式。创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对

    2024年02月09日
    浏览(58)
  • 11 结构型模式- 代理模式

    结构性模式一共包括七种: 代理模式、桥接模式、装饰者模式、适配器模式、门面(外观)模式、组合模式、和享元模式。 1 代理模式介绍 软件开发中的代理 : 代理模式中 引入了一个新的代理对象 ,代理对象在客户端对象和目标对象之间起到了中介的作用,它去掉客户不能看到

    2024年02月08日
    浏览(39)
  • 设计模式--------结构型模式

    结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构

    2024年02月13日
    浏览(48)
  • 设计模式结构型——外观模式

    目录 什么是外观模式 外观模式的实现 外观模式角色 外观模式举例 外观模式类图 外观模式代码实现 外观模式的特点 优点 缺点 注意事项 应用场景 总结         外观模式(Facade Pattern):又叫作门面模式,归属于结构型模式。外观模式定义了提供了定义了一个统一的高层

    2024年02月16日
    浏览(55)
  • 设计模式之结构型模式

    本文已收录于专栏 《设计模式》   大话设计模式主要分为三部分,第一部分是创建型模式,第二部分是结构型模式,第三部分是行为型模式。至于为什么要分为这三部分,我的理解是创建型是用于创建对象的而结构型是发生在类与类之间的关系是比较宏观的,比如说组合

    2024年02月11日
    浏览(38)
  • 结构型设计模式——桥接模式

    桥接模式(Bridge pattern): 使用桥接模式通过将实现和抽象放在两个不同的类层次中而使它们可以独立改变。 桥接模式 (Bridge) 是一种结构型设计模式, 可将 抽象 部分与 实现 部分 分离 ,使它们都可以独立的变化。如果一个系统需要在构件的抽象化角色和具体化角色之间增加更

    2024年02月07日
    浏览(48)
  • 结构型设计模式——外观模式

    有句话说这个世界就是个草台班子,只不过排面做的好看而已,里面都是一包糠。这句话来形容外观模式非常准确,外观模式又叫门面模式,顾名思义一个系统我不管你里面有多复杂有多少屎山代码,我只要求你提供的接口好用,简单就行,即门面要有排面!用专业的话讲是

    2024年01月22日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包