java里什么是代理

比如A是一个接口,B是被加强对象,C是代理对象

A接口有一个say()方法,B实现了A接口,C也实现了A接口,C在自己实现的say()方法里不但执行了B的say()方法也执行了一些自己的程序,这就是代理。

代理分为静态代理和动态代理。

为什么要代理

类的增强可以通过继承来实现,那如果想让某个方法增强呢?这时候就用到代理了。

如何代理?

大体上有目标类,代理类,增强(通知),连接点。

代理类在连接点处通过增强(通知)来对目标类进行增强。

我简单理解成增强就是在目标执行某方法进行拦截时执行的代码,拦截就是对方法或者参数进行分析,具体拦截后怎么做自己想怎么写就怎么写。

连接点是指那些被拦截到的点,大白话就是在哪些方法中拦截,总不能所有目标类的方法都拦截吧,只拦截我想要增强的方法就行了,在Spring中这些点指的是方法因为Spring只支持方法类型的连接点

静态代理的用途

控制真实对象的访问权限 通过代理对象控制对真实对象的使用权限。

避免创建大对象 通过使用一个代理小对象来代表一个真实的大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。

增强真实对象的功能 这个比较简单,通过代理可以在调用真实对象的方法的前后增加额外功能。

代理分为静态代理和动态代理

静态代理:

1、代理对象和目标对象都要实现的   公共接口

2、代理对象持有目标对象引用,重写构造方法,

3、实现共同的方法,代理对象增强行为。

缺点:

代理角色固定,一次只能代理一个对象。

接口

  1. public interface Marry {
    void marry();
    }

目标对象

  1. public class You implements Marry {
    public void marry() {
    System.out.println("sihai get marry");
    }
    }

代理对象

  1. public class MarryCompany implements Marry {
    private You you;
    public MarryCompany(You you) {
    this.you = you;
    }
    public void marry() {
    before();
    you.marry();
    after();
    }
    private void after() {
    System.out.println("get after work done");
    }
    private void before() {
    System.out.println("get ready for marry");
    }
    }

测试

  1. public class TestMarry {
    public static void main(String[] args) {
    You you = new You();
    MarryCompany marryCompany = new MarryCompany(you);
    marryCompany.marry();
    }
    }

结果

  1. get ready for marry
    sihai get marry
    get after work done

动态代理

根据需要通过反射机制在程序运行期动态的为目标对象创建代理对象,代理的行为可以代理多个方法,即满足生产需要的同时又达到代码的通用目的。

问题1.不能手动的为每一个目标都写代理。

那么多目标,一个一个写是不是太浪费时间了?

这时有两种解决方案:

(1)JDK的动态---运行过程代理,启动快执行慢,首选,必须接口实现,JDK动态代理的过程中,生成的动态代理对象与目标对象是同一接口实现
(2)CGLIB的动态代理---从字节级别代理,启动比JDK费时间但执行快,会为每一个目标类生成对应的子类

问题2.对于增强,不能写成硬编码

硬编码是说写死的编码,增强的方法都写死固然会很繁琐

JDK的动态代理

实现JDK的动态代理有两部分最重要:

1.动态代理对象的生成(需要类加载器,实现接口类型,调用处理程序,源码这样写的)

2.调用处理程序(执行的增强方法)

举个栗子:

接口类

public interface DogI {void say();
}

目标类

public class Dog implements DogI{@Overridepublic void say() {System.out.println("hello");}}

动态生成代理对象的类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class DogJDKPROXY implements InvocationHandler {//target为传进来的目标类private Object target;//获取传进来的目标类,并获取目标类的 类加载器,类接口,this指的是调用此方法的目标(还是目标类),需要实现InvocationHandler接口,重写invoke方法并执行public Object getProxyObject(Object target) {this.target=target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}//在这里可以进行拦截,加强之类的操作,我这里什么增强都没写@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//代理的类,执行的方法,传递的参数Object result = method.invoke(target, args);return result;}
}

测试

public class Test {public static void main(String[] args) {DogI dog =(DogI) new DogJDKPROXY().getProxyObject(new Dog());dog.say();}
}

JDK的动态代理是生成 目标类 的 接口对象 ,是接口对象!

CGLIB的动态代理

目标类

public class Person {public void say() {System.out.println("hello");}
}

动态生成代理对象的类

import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;public class PersonCGLIBProxy implements MethodInterceptor{//target为传过来的目标类private Object target;//获取目标类,需要Enhancer对象获取目标类的,然后从字节码的级别创造代理对象,设置setCallback才能拦截(增强),把目标类放进去实现MethodInterceptor并重写interceptpublic Object getProxyObject(Object target) {this.target=target;Enhancer enhancer=new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();}//这个方法就是增强的地方,arg0为生成的代理对象,arg1传进来的需要增强的方法(这里默认目标类的方法都拦截了)@Overridepublic Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy methodProxy) throws Throwable {Object result=methodProxy.invoke(target, arg2);return result;}
}

测试

public class Test {public static void main(String[] args) {Person p = (Person) new PersonCGLIBProxy().getProxyObject(new Person());p.say();}
}

对比一下两者发现非常相似,都是传过来一个目标类,然后获取这个目标类的某些东西,然后创建一个代理类,如果代理类执行方法,就会通过一个固定的方法来获取这个方法以及这个方法的参数,然后在代理类的这个方法里进行一些处理。

但是:使用动态代理机制虽然解决了代理对象的生成问题,但是要为对象的哪个方法增强,以及增强应该如何实现等等,没有实现这样的功能,所以非常不灵活

为了解决这个方法,可以使用Spring的AOP解决。

动态代理的用途

Java的动态代理,在日常开发中可能并不经常使用,但是并不代表他不重要。Java的动态代理的最主要的用途就是应用在各种框架中。因为使用动态代理可以很方便的运行期生成代理类,通过代理类可以做很多事情,比如AOP,比如过滤器、拦截器等。

在我们平时使用的框架中,像servlet的filter、包括spring提供的aop以及struts2的拦截器都使用了动态代理功能。我们日常看到的mybatis分页插件,以及日志拦截、事务拦截、权限拦截这些几乎全部由动态代理的身影。

总结:

如何简单描述java中的代理模式相关推荐

  1. 轻松学,Java 中的代理模式(proxy)及动态代理

    我们先来分析代理这个词. 代理 代理是英文 Proxy 翻译过来的.我们在生活中见到过的代理,大概最常见的就是朋友圈中卖面膜的同学了. 她们从厂家拿货,然后在朋友圈中宣传,然后卖给熟人. 按理说,顾客 ...

  2. 轻松学,Java 中的代理模式及动态代理

    前几天我写了<秒懂,Java 注解 (Annotation)你可以这样学>,因为注解其实算反射技术中的一部分,然后我想了一下,反射技术中还有个常见的概念就是动态代理,于是索性再写一篇关于动 ...

  3. JAVA面试要点006---.net中的委托与java中的代理模式和委托

    1.1.1 定义 委托是一种引用方法的类型.一旦为委托分配了方法,委托将与该方法具有完全相同的行为.委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示: //Code in C# ...

  4. Java中的代理模式

    1.什么是代理模式 代理模式:就是为其他对象提供一种代理以控制对这个对象的访问. 代理可以在不改动目标对象的基础上,增加其他额外的功能(扩展功能). 举个例子来说明代理的作用: 一般我们想邀请明星来当 ...

  5. 模式代码 java中aes_深入浅出:Java中的代理模式

    代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象,用来在系统中对原始的接口进行替换,然后在内部做一些增强处理.代理模式不会破坏系统的原有接口,不去修改原有的 ...

  6. Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别

    视频功能审核通过了,可以看视频啦!记得点关注啊~ 注意:因为网络原因,视频前一两分钟可能会比较模糊,过一会儿就好了 记得点关注啊,视频里的wx二维码失效了,wx搜索:"聊5毛钱的java&q ...

  7. Spring中的代理模式

    Spring中的代理模式,是Spring中一大核心 AOP(切面编程)的底层实现. 代理模式可分为: 静态代理 动态代理 静态代理 涉及三类角色,简单分析一下: 抽象角色(一般会使用接口或抽象类解决) ...

  8. Android中的代理模式

    Android中的代理模式 1. 什么是代理 比如我们生活中的找出租屋,需要去找中介进行寻找挑选.而这里的中介就是代理.列子中看出代理特点如下1. 租客跟中介要做成的最终目的是一致的就是租到房子(目标 ...

  9. Java 设计模式_代理模式(2016-08-19)

    概念: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 就是一个人或者机构代表另一个人或者机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...

  10. Java中的贷款模式(又名贷方承租人模式)

    这篇文章是关于在Java中实现贷款模式的. 用例 在保存资源的代码与访问资源的代码之间实现分离,从而使访问代码无需管理资源. 当我们编写用于读取/写入文件或查询SQL / NOSQL数据库的代码时,上 ...

最新文章

  1. python统计字符串汉字个数_Python使用递归计算字符串中的字符数
  2. Crypto API
  3. Linux下配置rdate时间服务器
  4. 怎样用命令行生成自己的签名文件keystore
  5. 2020\Simulation_2\4.括号序列
  6. 网狐动态数组CWHArray
  7. Eclipse创建java webproject配置Tomacat和JDK
  8. 在斯坦福,做 Manning 的 phd 要有多强?
  9. Android 系统(164)---手机收到8bit编码的短信无法显示
  10. 客户和服务器之间响应的序列,Redis的请求/响应协议和往返时间详解
  11. 201521123059 《Java程序设计》第三周学习总结
  12. [CTSC2018]假面(概率DP)
  13. unity Scene窗口的任意比例放大和缩小
  14. HTTP 长连接 使用场景
  15. 知了课堂 python_知了传课 - 主页
  16. 测试开发工程师简历模版
  17. 如何一个月左右拿下PAT甲级(浙大机试)满分
  18. JUnit5学习之一:基本操作
  19. matlab柱状图设置条纹,matlab代码画条纹柱状图
  20. VSCode小说神器Thief-Book-VSCode页数获取

热门文章

  1. 如何让sublime编译c语言,如何在Sublime Text 3中编译C程序?
  2. 单片机C语言控制16*16LED显示屏,基于单片机的pwm控制16*16led点阵亮度调节怎么做啊,...
  3. 自动驾驶 11-2: 激光雷达传感器模型和点云 LIDAR Sensor Models and Point Clouds
  4. 2012年之前Mac Book pro 安装新系统macOS 10.15 Catalina 制作U盘启动盘
  5. 写jsx_使用Vue 3.0做JSX(TSX)风格的组件开发
  6. ad如何计算电路板的pin数量_PCB厂一到八层电路板的叠层设计方式
  7. DSSM核心思想是把查询文本(query)和内容文本(doc)映射到同维度的语义空间中, 以最优化查询文本和内容文本的语义向量之间的余弦相似度为目的
  8. 215.数组中的第K个最大元素
  9. 创建一个超链接,点击这个超链接,显示数据库中的数据信息:MVC模式查询
  10. 最大熵模的理解与最大熵模型逻辑回归相似转换条件