JAVA基础(一)——代理模式

实现java代理一般分为静态代理和动态代理(jdk代理和cglib代理)

代理模式

简单的说就是对原有的业务进行代理,外界通过代理访问真实对象,代理类似现在的中介机构,房产中介就是一个代理,代理房东,租户只要找到代理而无须关心房东是谁,代理能在房东的基础上增强房东的行为。

代理模式代码

JAVA静态代理

业务接口

package com.rrg.proxy.jdk.staticProxy;
/**
 *
 * @author abc
 *
 */
public interface Count {
    /**
     * 查询余额
     */
    public void queryMoney();

    /**
     * 转账
     */
    public void transferMoney();
}

业务实现类

package com.rrg.proxy.jdk.staticProxy;

public class CountImpl implements Count {

    public void queryMoney() {
        System.out.println("queryMoney()");
    }

    public void transferMoney() {
        System.out.println("transferMoney()");
    }

}

代理

package com.rrg.proxy.jdk.staticProxy;
/**
 * java静态代理
 * @author abc
 *
 */
public class JDKStaticProxy implements Count {

    private CountImpl countImpl;

    public JDKStaticProxy(CountImpl countImpl) {
        this.countImpl = countImpl;
    }

    public void queryMoney() {
        System.out.println("===开始查询===");
        countImpl.queryMoney();
        System.out.println("===查询结束===");
    }

    public void transferMoney() {
        System.out.println("===开始转账===");
        countImpl.transferMoney();
        System.out.println("===转账成功===");
    }

}

测试

/**
     * jdk静态代理
     */
    @Test
    public void test1(){
        CountImpl impl = new CountImpl();
        JDKStaticProxy proxy = new JDKStaticProxy(impl);
        proxy.queryMoney();
        System.out.println();
        proxy.transferMoney();
    }

JAVA动态代理

模拟业务方法接口UserService.java

package com.rrg.proxy.jdk.dynamic;
/**
 * 创建业务接口
 * @author abc
 *
 */
public interface UserService {
    /**
     * 新增人员
     */
    public void add();
}

业务方法实现UserServiceImpl.java

package com.rrg.proxy.jdk.dynamic;

public class UserServiceImpl implements UserService {

    public void add() {
        System.out.println("add()");
    }

}

代理类,负责处理代理

package com.rrg.proxy.jdk.dynamic;

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

public class JDKDynamicHandler implements InvocationHandler {

    private UserService userService;

    public JDKDynamicHandler(UserService userService) {
        super();
        this.userService = userService;
    }

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

        System.out.println("===添加人员处理===");
        Object result = method.invoke(userService, args);
        System.out.println("===添加人员完毕===");

        return result;
    }

    public Object getProxy() {
        //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用
        //创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据,在包装方法是调用真正的业务方法)、接口、handler实现类

        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), this.userService.getClass().getInterfaces(), this);
    }
}

测试

/**
     * jdk动态代理
     */
    @Test
    public void test2() {
        UserService userService = new UserServiceImpl();
        JDKDynamicHandler handler = new JDKDynamicHandler(userService);
        UserService proxy = (UserService) handler.getProxy();
        proxy.add();
    }

CGLIB动态代理

不需要接口直接代理实现类

业务实现类

package com.rrg.proxy.cglib;

public class BookFacadeImpl {

    /**
     * 添加图书
     */
    public void addBook() {
        System.out.println("addBook()");
    }
}

代理

package com.rrg.proxy.cglib;

import java.lang.reflect.Method;

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

public class BookFacadeCglib implements MethodInterceptor {

    private BookFacadeImpl bookService;

    public Object getInstance(BookFacadeImpl bookService) {
        Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类
        enhancer.setSuperclass(this.bookService.getClass());  //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类)
        //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
        enhancer.setCallback(this);
        // 创建动态代理类对象并返回
        return enhancer.create();
    }
    //回调方法
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("===准备添加图书===");
        methodProxy.invokeSuper(object, args);
        System.out.println("===完成添加图书===");
        return null;
    }

}

测试

/**
     * cglib动态代理
     */
    @Test
    public void test3() {
        BookFacadeImpl bookService = new BookFacadeImpl();
        BookFacadeCglib cglib = new BookFacadeCglib();
        BookFacadeImpl bookCglib = (BookFacadeImpl) cglib.getInstance(bookService);
        bookCglib.addBook();
    }

总结

(1)静态代理是在编译时创建一个业务代理类,通过代理访问同名方法,实现对原方法的包装(代理类继承业务类)
(2)JDK动态代理通过接口的方法名,在动态的代理类调用同名业务方法,实现对原方法的包装(实现InvocationHandler)
(3)CGLIB动态代理通过继承业务类,创建出一个增强的业务类(实现MethodInterceptor)

代理是一个AOP思想的体现,切面编程对业务方法的前后进行增强

在Spring的AOP编程中:
  如果加入容器的目标对象有实现接口,用JDK代理
  如果目标对象没有实现接口,用Cglib代理

时间: 2024-08-04 16:11:55

JAVA基础(一)——代理模式的相关文章

JAVA设计模式之代理模式

学编程吧JAVA设计模式之代理模式发布了,欢迎通过xuebiancheng8.com来访问 一.概述 给某一个对象提供一个代理,并由代理对象来完成对原对象的访问.代理模式是一种对象结构型模式. 二.适用场景 当无法直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口. 三.UML类图 四.参与者 1.接口类:Subject 它声明了真实访问者和代理访问者的共同接口,客户端通常需要针对接口角色进行编程. 2.代理类

JAVA设计模式(3)----代理模式

1.  什么是代理模式?Proxy Pattern 代理模式定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 通俗的讲,代理模式就是我很忙没空理你,你要想找我可以先找我的代理人,代理人和被代理人继承同一个接口.代理人虽然不能干活,但是被代理的人可以干活. 这个例子中有水浒传中的这么几个人:名垂青史的潘金莲,王婆,西门大官人.西门庆想要找潘金莲,需要找王婆做代理.首先定义一个接口:Kin

java设计模式6——代理模式

java设计模式6--代理模式 1.代理模式介绍: 1.1.为什么要学习代理模式?因为这就是Spring Aop的底层!(SpringAop 和 SpringMvc) 1.2.代理模式的分类: 静态代理 动态代理 1.3.代理模式关系图(以租房子为例) 2.静态代理 2.1.角色分析: 抽象角色:一般会使用接口或者抽象类来解决 真实角色:被代理的角色 代理客户:代理真实角色.代理真实角色后,我们一般会做一些附属的操作 客户:访问代理对象的人 2.2.例1(租房子演示) 2.2.1.抽象角色实现(

Java中的代理模式

1.什么是代理模式 代理模式:就是为其他对象提供一种代理以控制对这个对象的访问. 代理可以在不改动目标对象的基础上,增加其他额外的功能(扩展功能). 举个例子来说明代理的作用: 一般我们想邀请明星来当我们的代言人,我们并不能直接联系到明星,而是通过其经纪人,来告诉经纪人我们需要和明星进行合作,然后通过经纪人来转达给明星.,明星只需要做好代言工作就好,其他繁琐的事情就交于经纪人就可以.这里的经经纪人就是一个代理对象,明星就是一个目标对象. 用图表示如下: 2.三种代理模式  2.1 静态代理 静态

Java基础-静态代理以及动态代理

动态代理: 在了解动态代理之前,先对代理有一个认识. 代理模式是Java常见的设计模式之一.所谓代理模式是指客户端并不直接调用实际的对象,而是通过调用代理,来间接的调用实际的对象. 打个比方:你买火车票的时候,并不直接花钱购买, 而是将钱预先垫付到抢票软件上, 使抢票软件为你购买, 你要做的行为就是买票,抢票软件就是你的代理 代理对象控制对被代理对象的访问: 这是代理的通用模型图 Subject:定义了被代理角色和代理角色的共同接口或者抽象类,也就是subject中定义了共同接口opration

Java与设计模式-代理模式

代理模式也称为委托模式,属于结构型设计模式,为其他对象提供一种代理,以控制对这个对象的访问.这么听起来很难理解,生活中代理的例子也是很多的,毕业了要找房子,怎样又快又好的找到自己心仪的房子,必须通过租房代理:想要买火车票,火车站太远,我们可以选择代理点进行购票.代码模式的UML类图如下: 应用场景:当无法或不想直接访问某个对象或访问某个对象存在困难时可以通过一个代理对象来间接访问,为了保证客户端使用的透明性,委托对象与代理对象需要实现相同的接口.下面我们以"秋菊打官司"为例,讲解一下代

java设计优化--代理模式

代理模式使用代理对象完成用户的请求,屏蔽用户对真实对象的访问. 代理模式的用途很多,比如因为安全原因,需要屏蔽客户端直接访问真实对象:或者在远程调用中,需要使用代理对象处理远程方法中的技术细节:或者为了提升系统,对真是对象进行封装,从而达到延迟加载的目的. 在系统启动时,将消耗资源最多的方法使用代理模式分离,就可以加快系统的启动速度,减少用户的等待时间.在用户真正在做查询是,再由代理类加载真实的类,完成用户请求.这就是使用代理模式达到延迟加载的目的. 1.静态代理实现: 主题接口: 1 publ

Java设计模式:代理模式(一)

问题的提出 现在生活中,常常在微信朋友圈里面看到代购的信息,你想在国外买什么,香港买什么,但是又懒得自己过去,于是常常委托别人帮忙买奶粉买那啥的.这类问题的缘由是因为客户和原产地没有直接的接触,所以需要一个代理(代购)的第三者来实现间接引用.代理对象可以在客户端和目标对象间起到中介作用,而且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务.代理模式是一种很好实现客户对象与代理对象分离的策略.其抽象UML图如下图 代理模式包含如下角色 ISubject:抽象主题角色,是一个接

Java记录 -90- 静态代理模式深度剖析

代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理地下可以在客户端和目标对象之间起到中介的作用. 代理模式一般涉及到三个角色: 1.抽象角色:声明真实对象和代理对象的共同接口: 2.代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他操作,相当于对真实对象进行封装: 3.真实角色

Java设计模式——Proxy(代理)模式

Proxy(代理)模式为对象提供一个代理或者占位来控制对该对象的访问. 图像代理 使用Proxy模式的设计有时非常脆弱,它们依赖转发方法来调用其底层对象.转发可能会建立一个非常脆弱并且需要经常维护的设计. load()方法以JFrame对象为参数,用于在指定图像加载完毕之后进行回调.在执行load()方法的时候,它先以LOADING引用的图像对象为参数调用setImage(),然后重新绘制图形显示窗口,最后为自己启动一个单独的线程.而run()方法是在单独的线程中执行的,该方法根据构造器中指定的