代理设计模式
代理设计模式的基本形式
代理设计模式的核心思路,一个接口两个子类,一个子类完成核心业务操作,另一个完成与核心业务有关的辅助性操作。例如,编写一个简单的设计模式。
package com.hbsi.test;
interface Food{
public void eat();
}
class ProxyFood implements Food{
private Food food;
public ProxyFood(Food food) {
this.food = food;
}
public void after() {
System.out.println("饭后");
}
public void before() {
System.out.println("饭前");
}
@Override
public void eat() {
this.after();
this.food.eat();//调用RealFood中的eat方法
this.before();
}
}
class RealFood implements Food{
@Override
public void eat() {
System.out.println("吃饭 ,,,,,RealFood");
}
}
public class ProxyDemo {
public static void main(String[] args) {
Food f = new ProxyFood(new RealFood());
f.eat();
}
}

 在什么情况下代理设计模式可能会被使用?最常用的形式就是在系统日志上进行,

 
动态代理类
传统的代理模式都是一个接口两个子类,一个是真实主题类,另一个是代理类,这样就导致了,一个代理类只能为一个接口服务,所以在java中提供了动态代理的支持。
如果要实现动态代理类,必须采用InvocationHandle接口处理。
此接口中定义了一个invoke方法:
Object invoke​(Object proxy, Method method, Object[] args) throws Throwable
处理代理实例上的方法调用并返回结果。
在这个invoke方法里面接受的参数如下,
1. proxy:代理的对象,
2. method:表示真实主题要调用的执行方法;
3. args:调用方法时所传递的参数
而在invoke'方法里面会返回一个Object的数据,这个数据就是调用方法时,返回的结果
但是所哟的真实主体累,都需要返回一个代理类对象,而这个代理类对象都由Proxy类完成,在Proxy类中的一个操作方法:
返回指定接口的代理实例,该代理实例将方法调用分派给指定的调用处理程序。
在此方法中有以下参数:
loader :返回目标对象的类加载器;读取要代理类的代码,重新实例化一个新的
interfaces:返回一个类实现的所有接口
h:InvocationHandler 接口对象,完成真正的代理操作。
代码示例:建立一个动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyProxyd implements InvocationHandler{
private Object target;//要代理的对象信息
public Object bind(Object target) {
this.target = target;//赋值
//返回与当前传入对象结构相同的代理类对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces() , this);
}
@Override//参数说明:代理的对象。表示真实主体类要执行的方法。方法需要的参数
public Object invoke(Object proxy, Method method, Object[] arg) throws Throwable {
this.log();
Object invoke = method.invoke(this.target, arg);//调用真实类的方法
this.commit();
return invoke;
}
private void log() {
System.out.println("执行记录日志方法");
}
private void commit() {
System.out.println("事务提交");
}
public static void main(String[] args) {
Food f = (Food) new MyProxyd().bind(new RealFood());
f.eat();
}
}
public class RealFood implements Food{
@Override
public void eat() {
System.out.println("吃饭 ,,,,,RealFood");
}
}

 

CGLIB代理模式、
从标准的代理设计模式来讲,一定要有借口,而且通过之前的动态代理也可以发现,如果想要去的代理类对象,就必须传入接口。
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces() , this);
使用Proxy必须传入所有接口,否则代理不能使用。为了解决java动态代理的必须需要接口的弊端,CGLIB可以解决此问题。
cglib包中需要使用以下几个类:
1. net.sf.cglib.proxy.Enhancer,相当于 Proxy 功能,返回代理对象
2. net.sf.cglib.proxy.MethodInterceptor接口:处理一个代理操作的接口
3. net.sf.cglib.proxy.MethodProxy:代替之前的Method类的功能
代码范例:基于类实现的动态代理设计模式
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class PrintMes {
public void print() {
System.out.println("吃饭 ,,,,,");
}
}
public class CGLIBProxy {
public static void main(String[] args) {
PrintMes mes = new PrintMes();//
Enhancer enhancer = new Enhancer();//代理类对象
enhancer.setSuperclass(mes.getClass());//为代理类设置一个父类,自我理解就是做关联
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] objs, MethodProxy proxy) throws Throwable {
System.out.println("饭前洗手");
return method.invoke(mes, args);
}
});
PrintMes create = (PrintMes) enhancer.create();//返回代理对象
create.print();//调用
}
}

java--动态代理设计模式,CGLIB实现的动态代理设计模式的更多相关文章

  1. 性能优于JDK代理,CGLib如何实现动态代理

    按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建 ...

  2. java提供类与cglib包实现动态代理

    终于有点空余时间,决定把之前学习的知识点整理一下,备以后复习. 动态代理有三角色:抽象角色,代理角色,真是角色. 第一个记录下java提供的动态代理.即使用Proxy类和InvocationHande ...

  3. java动态代理--proxy&cglib

    大纲 代理 proxy cglib 小结 一.代理 为什么要用代理?其实就是希望不修改对象的情况下,增强对象. 静态代理: 静态代理模式,需要代理类和目标类实现同一接口,代理类的方法调用目标类的方法, ...

  4. 学习CGLIB与JDK动态代理的区别

    动态代理 代理模式是Java中常见的一种模式.代理又分为静态代理和动态代理.静态代理就是显式指定的代理,静态代理的优点是由程序员自行指定代理类并进行编译和运行,缺点是一个代理类只能对一个接口的实现类进 ...

  5. CGLib方式对接口实现代理

    JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了.CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采 ...

  6. java设计模式(一)动态代理模式,JDK与CGLIB分析

    -本想着这个知识点放到Spring Aop说说可能更合适一点,但因为上一篇有所提到就简单分析下,不足之处请多多评论留言,相互学习,有所提高才是关键! 什么是代理模式: 记得有本24种设计模式的书讲到代 ...

  7. Java动态代理与Cglib库

    JDK动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在 ...

  8. Java代理(jdk静态代理、动态代理和cglib动态代理)

    一.代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强.加入一些非业务性代码,比如事务.日志.报警发邮件等操作. 二.jdk静态代理 1.业务接口 /** * 业务接 ...

  9. [z]Java代理(jdk静态代理、动态代理和cglib动态代理)

    一.代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强.加入一些非业务性代码,比如事务.日志.报警发邮件等操作. 二.jdk静态代理 1.业务接口 1 2 3 4 5 ...

  10. 代理模式 & Java原生动态代理技术 & CGLib动态代理技术

    第一部分.代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常 ...

随机推荐

  1. DEBUG技巧1 SE37将参数保存为测试数据

    1. SE37调试函数的时候,将参数保存为测试数据,供下次调试使用, 或者参考标准的赋值进行赋值 2. SE37 ->执行-> 测试序列 测试函数: CO_XT_COMPONENTS_DE ...

  2. intellij 插件的使用

    目录 intellij 插件的使用 插件的设置 插件推荐 @(目录) intellij 插件的使用 插件的设置 在 IntelliJ IDEA 的安装讲解中我们其实已经知道,IntelliJ IDEA ...

  3. VS2010/VS2012/VS2015下openGL环境配置(转)

    按:按照下述博文,三个例子均成功. https://blog.csdn.net/so_geili/article/details/51685005 请仔细阅读每一个字. 为了学习<OpenGL超 ...

  4. web端自动化——selenium测试报告生成、找到测试报告路径、实现发邮件(整合)

    有这样的一个场景: 假设生成的测试报告与多人相关,每个人都去测试服务器査看就会比较麻烦,如果把这种主动的且不及时的査看变成被动且及时的査收,就方便多了. 整个程序的执行过程可以分为三个步骤: ①    ...

  5. C# 基于Directshow.Net lib库 USB摄像头使用DirectShow.NET获取摄像头视频流

    https://blog.csdn.net/u010118312/article/details/91766787 https://download.csdn.net/download/u010118 ...

  6. qbittorrent搜索在线插件

    https://raw.githubusercontent.com/khensolomon/leyts/master/yts.py https://raw.githubusercontent.com/ ...

  7. 【bcrypt】vue项目中bcrypt安装报错

    [报错] 报错时安装方法: npm install bcrypt [解决方法] npm install bcryptjs 用 bcryptjs 替换 bcrypt 即可.

  8. Transformer的numpy实现

    下面的代码自下而上的实现Transformer的相关模块功能.这份文档只实现了主要代码.由于时间关系,我无法实现所有函数.对于没有实现的函数,默认用全大写函数名指出,如SOFTMAX 由于时间限制,以 ...

  9. Linux将.deb以绿色免安装的方式“安装”

    1.如果是xxx.deb文件,一般网上都是教你dkpg -i xxx.deb,但是这种方式类似windows里的安装,可能会在很多地方生成一些“垃圾”数据[比如不需要在dpkg安装应用信息文件里写入此 ...

  10. NumPy使用图解教程

    NumPy是Python中用于数据分析.机器学习.科学计算的重要软件包.它极大地简化了向量和矩阵的操作及处理.python的不少数据处理软件包依赖于NumPy作为其基础架构的核心部分(例如scikit ...