动态代理+静态代理+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冲突 - ...
随机推荐
- ES6+Webpack+Babel基本环境搭建
### 本文基本是流水文,记录学习中步骤,希望对看到的你有用,蟹蟹. 基本环境搭建 技术栈 Webpack ES6 Babel 开发环境 VS Code Node 搭建环境过程 新建项目文件夹
- redis简介与window安装:
redis简介与window安装: 花开堪折直需折,莫待无花空折枝 Redis 概念:Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(ke ...
- JAVA_基础反射创建运行时类的对象
通过反射去创建对应的运行时类的对象 newInstance():调用此方法,创建对应的运行时类的对象.内部调用的是空参的构造器. 要想此方法正常的创建运行时类的对象,要求: 1.运行时类必须提供空参构 ...
- Serverless 如何应对 K8s 在离线场景下的资源供给诉求
本文整理自腾讯云云原生产品团队的专家产品经理韩沛在 Techo 开发者大会云原生专题的分享内容--Kubernetes 混部与弹性容器.本次分享主要分为三部分:基于 K8s 的应用混部.提升应用混部效 ...
- 树莓派-4WD智能小车操作小结
树莓派-4WD智能小车操作小结 树莓派4B-4WD智能小车,双层结构,第一层结构为:小车扩展板(底层)+树莓派主板,通过铜柱隔离固定,小车扩展板相当于计算机的外设扩展板:上面一层为第二层,是三个舵机承 ...
- 【Flutter】可滚动组件之GridView
前言 GridView可以构建一个二维网格列表.需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout).Sl ...
- java8新特性之stream流
Stream 流是 Java 8 提供给开发者一套新的处理集合的API,他把我们将要处理的集合作为流,就像流水线一样,我们可以对其中的元素进行筛选,过滤,排序等中间操作,只不过这种操作更加简洁高效. ...
- python3.6安装教程
Python代码要运行,必须要有Python解释器.Python3.x的版本是没有什么区别的,这里以3.6版本来演示安装的过程.这里只介绍Windows环境下的安装. 下载安装程序 Python官方的 ...
- 【Jboss】一台服务器上如何部署多个jboss
一台服务器上如何部署多个jboss呢?直接把整个部署环境copy一份到相应的目录下? 这样只是前提,但是启动复制后的jboss就会发现,有很多端口被占用 3873,8080,8009,8443,808 ...
- go语言循环变量
阅读go语言圣经第五章第六节介绍到了捕获迭代变量 package main import ( "fmt" ) func main() { var lis []func() for ...