动态代理+静态代理+cglib代理 详解
代理定义:
代理(Proxy):是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。
好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
动态代理+静态代理+cglib代理 区别:
1、静态代理===>>>代理对象与目标对象要实现相同的接口或者是继承相同父类, 然后通过调用相同的方法来调用目标对象的方法
2、动态代理===>>>代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理。
3、cglib代理===>>>目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现的Cglib代理。
静态代理总结:
1.优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展。
2.缺点 :因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护。
动态代理总结:
1.优点:代理对象,不需要实现接口,也叫做:JDK代理,接口代理。
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)。
cglib代理总结:
1.优点:Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
2.缺点:Cglib原理是针对目标类生成一个子类,覆盖其中的所有方法,所以目标类和方法不能声明为final类型。
下面上代码:
(一)动态代理:
package com.example.demo.test.dynamic.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import lombok.Data; /**
* 创建动态代理对象
* 动态代理不需要实现接口,但是需要指定接口类型
*/
public class ProxyFactory { //维护一个目标对象
private Object target; public ProxyFactory(Object target) {
this.target = target;
} //给目标对象生成代理对象
public Object getProxyInstance() { System.out.println("==>>开始代理事务");
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(target, args);
}
}
);
} }
package com.example.demo.test.dynamic.proxy;
public interface IUserDao {
void save();
void delete();
void saveAndDelete();
}
package com.example.demo.test.dynamic.proxy;
public class UserDao implements IUserDao {
public void save() {
System.out.println("====save");
}
public void delete() {
System.out.println("====delete");
}
public void saveAndDelete() {
save();
delete();
}
}
===>>>测试:
package com.example.demo.test.dynamic.proxy; /**
* @date: 2020/12/11 19:55
* @description:
*/
public class Client { public static void main(String[] args) {
// 目标对象
UserDao target = new UserDao();
// class aop.UserDao
System.out.println(target.getClass()); // 给目标对象,创建代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
// class $Proxy0 内存中动态生成的代理对象
System.out.println(proxy.getClass());
System.out.println("=========================");
proxy.save();
proxy.delete();
proxy.saveAndDelete();
}
}
(一)静态代理:
package com.example.demo.test.proxy; /**
* 代理对象,静态代理
*/
public class UserDaoProxy implements IUserDao{ //接收保存目标对象
private IUserDao target; public UserDaoProxy(IUserDao target) {
this.target = target;
} public void save() {
System.out.println("开始代理...");
target.save();
}
}
package com.example.demo.test.proxy; /**
* 接口
*/
public interface IUserDao { void save();
}
package com.example.demo.test.proxy; /**
* 接口实现 目标对象
*/
public class UserDao implements IUserDao { public void save() {
System.out.println("----已经保存数据!----");
} }
===>>>测试:
package com.example.demo.test.proxy; /**
* 测试类
*/
public class AppTest { public static void main(String[] args) {
//目标对象
UserDao target = new UserDao(); //代理对象,把目标对象传给代理对象,建立代理关系
UserDaoProxy proxy = new UserDaoProxy(target); proxy.save();//执行的是代理的方法
}
}
(一)cglib代理:
package com.example.demo.test.cglib; import com.example.demo.test.dynamic.proxy.UserDao;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer; /**
* @date: 2020/12/11 20:07
* @description:
*/
public class CglibClient { public static void main(String[] args) { CglibProxyFactory cglibProxy = new CglibProxyFactory();
//jdk需要提供接口,cglib需要是非私有类,且不能处理final关键字修饰的方法
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(UserDao.class);
//设置回调对象
enhancer.setCallback(cglibProxy); UserDao proxy = (UserDao) enhancer.create();
proxy.save();
proxy.delete();
proxy.saveAndDelete();
}
}
package com.example.demo.test.cglib; import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /**
* @author: 乔利强
* @date: 2020/12/11 20:05
* @description:
*/
public class CglibProxyFactory implements MethodInterceptor { public CglibProxyFactory() {
} /**
* 1、代理对象;2、委托类方法;3、方法参数;4、代理方法的MethodProxy对象。
*
* @param obj
* @param method
* @param objects
* @param methodProxy
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("走代理方法......" + method.getName());
return methodProxy.invokeSuper(obj, objects);
}
}
动态代理+静态代理+cglib代理 详解的更多相关文章
- 静态代理和动态代理(jdk/cglib)详解
1.静态代理模式 代理模式上,基本上有Subject角色,RealSubject角色,Proxy角色.其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口:RealSu ...
- 大厂高级工程师面试必问系列:Java动态代理机制和实现原理详解
代理模式 Java动态代理运用了设计模式中常用的代理模式 代理模式: 目的就是为其他对象提供一个代理用来控制对某个真实对象的访问 代理类的作用: 为委托类预处理消息 过滤消息并转发消息 进行消息被委托 ...
- [转]反向代理过程与Nginx特点详解
原文链接:<Nginx搭建反向代理服务器过程详解> 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内 ...
- Nginx代理功能与负载均衡详解
序言 Nginx的代理功能与负载均衡功能是最常被用到的,关于nginx的基本语法常识与配置已在上篇文章中有说明,这篇就开门见山,先描述一些关于代理功能的配置,再说明负载均衡详细. Nginx代理服务的 ...
- nginx入门与实战 安装 启动 配置nginx Nginx状态信息(status)配置 正向代理 反向代理 nginx语法之location详解
nginx入门与实战 网站服务 想必我们大多数人都是通过访问网站而开始接触互联网的吧.我们平时访问的网站服务 就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务. Web ...
- CentOS 7 配置 Nginx 正向代理 http、https 最详解
手头项目中有使用到 nginx,因为使用的三方云服务器,想上外网需要购买外网IP的,可是有些需要用到外网却不常用的主机也挂个外网IP有点浪费了,便想使用nginx的反向代理来实现多台内网服务器使用一台 ...
- Java代理模式之Cglib代理
Cglib代理,也叫做子类代理.在内存中构建一个子类对象从而实现对目标对象功能的扩展. CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类.不鼓励直接使用ASM,因 ...
- 代理模式之Cglib代理
Cglib代理,也叫做子类代理.在内存中构建一个子类对象从而实现对目标对象功能的扩展. l JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口.如果想代理没有实现接口的类,就可 ...
- Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解
废话不多说,本文将会层层深入给大家讲解如何动态的生成一个完整的界面. 本文内容: Java代码中动态生成View Java代码中动态设置View的位置,以及其他的属性 LayoutParams详解 一 ...
- Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解
1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...
随机推荐
- Sqoop(四)增量导入、全量导入、减量导入
增量导入 一.说明 当在生产环境中,我们可能会定期从与业务相关的关系型数据库向Hadoop导入数据,导入数仓后进行后续离线分析.这种情况下我们不可能将所有数据重新再导入一遍,所以此时需要数据增量导入. ...
- 2020 年度编程语言排行榜出炉!C 语言称霸,Java 遭遇滑铁卢…….
最近,TIOBE 发布了过去一年的编程语言排行榜: 数据来源TIOBE: https://www.tiobe.com/tiobe-index/ TIOBE介绍: TIOBE编程语言索引是编程语言流行程 ...
- dede织梦技巧:教你彻底解决dede按权重排序的问题(转)
dede排序对网站来说一直存在问题,默认是按照最新发布时间排序.这样排序有个问题,一旦更新之后即被视为最新发布,于是原本做好的排序瞬间就乱了. 这种时候,按权重排序是个很好的选择,但按权重排序到处存在 ...
- 大数据专栏 - 基础1 Hadoop安装配置
Hadoop安装配置 环境 1, JDK8 --> 位置: /opt/jdk8 2, Hadoop2.10: --> 位置: /opt/bigdata/hadoop210 3, CentO ...
- db_install.rsp dbca.rsp netca.rsp 详解【转】
db_install.rsp详解 #################################################################### ## Copyright(c ...
- 几幅图,拿下 HTTPS
我很早之前写过一篇关于 HTTP 和 HTTPS 的文章,但对于 HTTPS 介绍还不够详细,只讲了比较基础的部分,所以这次我们再来深入一下 HTTPS,用实战抓包的方式,带大家再来窥探一次 HTTP ...
- 当Django设置DEBUG为False时,发现admin和html的静态资源文件加载失败的解决办法
当Django设置DEBUG为False时,发现admin和html的静态资源文件加载失败,折腾一段时间终于找到解决办法: 1.先在setting文件增加BASE_DIR(项目的路径) BASE_DI ...
- Linux简单Shell脚本监控MySQL、Apache Web和磁盘空间
Linux简单Shell脚本监控MySQL.Apache Web和磁盘空间 1. 目的或任务 当MySQL数据库.Apache Web服务器停止运行时,重新启动运行,并发送邮件通知: 当服务器磁盘的空 ...
- Can't locate Time/HiRes.pm in @INC (@INC contains
Can't locate Time/HiRes.pm in @INC (@INC contains: /usr/local/lib/perl5 /usr/local/share/perl5 /usr/ ...
- kubernets之服务重定向
一 服务的强大功能之处的其他表现 前面介绍的所有有关服务的说明,都是将集群内部的pod应用暴露出来提供外部客户端或者内部的客户端进行访问,但是服务的强大之处远远不止于此 服务甚至可以将集群外部的应用 ...