代理设计模式
代理设计模式的基本形式
代理设计模式的核心思路,一个接口两个子类,一个子类完成核心业务操作,另一个完成与核心业务有关的辅助性操作。例如,编写一个简单的设计模式。
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. intellij tomcat配置

    目录 intellij tomcat配置 @(目录) intellij tomcat配置 如上图标注 1 所示,我们可以切换随时为项目切换不同的容器. 如上图标注 2 所示,我们可以指定给运行的容器设 ...

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

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

  3. Cas(03)——Cas Server中各配置文件介绍

    Cas Server中各配置文件介绍 Cas Server中所有的配置文件都是放在WEB-INF目录及其子目录下的. 在WEB-INF/classes下的配置文件有: l  cas-theme-def ...

  4. docker里安装kali linux

    docker里安装kali linux 官网镜像 docker search kali docker pull kalilinux/kali-linux-docker vi /etc/apt/sour ...

  5. pt-kill MySQL会话杀灭神器

    废话不多说,直接上例子: pt-kill --host=127.0.0.1 --user=xxx --password=xxxxxx --port=xxxx --busy-time 10 --matc ...

  6. [Attention Is All You Need]论文笔记

    主流的序列到序列模型都是基于含有encoder和decoder的复杂的循环或者卷积网络.而性能最好的模型在encoder和decoder之间加了attentnion机制.本文提出一种新的网络结构,摒弃 ...

  7. git 版本控制中回溯到某个历史版本

    1.git log 查看之前的版本号 2. git reset --hard 版本号 3.git push -f -u origin 分支 恢复上一个版本是: git reset --hard HEA ...

  8. pycharm 提示:this license **** has been cancelled(2)

    pycharm安装激活过程中,提示 this license **** has been cancelled .这个问题并不是你的激活码不对,而是需要修改系统的hosts文件,下面详细讲解下如何修改h ...

  9. Python 绘图库Matplotlib入门教程

    0 简单介绍 Matplotlib是一个Python语言的2D绘图库,它支持各种平台,并且功能强大,能够轻易绘制出各种专业的图像. 1 安装 pip install matplotlib 2 入门代码 ...

  10. [Visual Studio] - 使用 Fiddler 时,禁止监控 VSHub 请求的方法

    背景 VS + Fiddler 调试 WebAPI,监控请求包含大量 VSHub Request.http://localhost:49161/vshub/bb195f2e0d5c4765b9411f ...