代理定义:
代理(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代理 详解的更多相关文章

  1. 静态代理和动态代理(jdk/cglib)详解

    1.静态代理模式 代理模式上,基本上有Subject角色,RealSubject角色,Proxy角色.其中:Subject角色负责定义RealSubject和Proxy角色应该实现的接口:RealSu ...

  2. 大厂高级工程师面试必问系列:Java动态代理机制和实现原理详解

    代理模式 Java动态代理运用了设计模式中常用的代理模式 代理模式: 目的就是为其他对象提供一个代理用来控制对某个真实对象的访问 代理类的作用: 为委托类预处理消息 过滤消息并转发消息 进行消息被委托 ...

  3. [转]反向代理过程与Nginx特点详解

    原文链接:<Nginx搭建反向代理服务器过程详解> 1.1 反向代理初印象 反向代理(Reverse Proxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内 ...

  4. Nginx代理功能与负载均衡详解

    序言 Nginx的代理功能与负载均衡功能是最常被用到的,关于nginx的基本语法常识与配置已在上篇文章中有说明,这篇就开门见山,先描述一些关于代理功能的配置,再说明负载均衡详细. Nginx代理服务的 ...

  5. nginx入门与实战 安装 启动 配置nginx Nginx状态信息(status)配置 正向代理 反向代理 nginx语法之location详解

    nginx入门与实战 网站服务 想必我们大多数人都是通过访问网站而开始接触互联网的吧.我们平时访问的网站服务 就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务. Web ...

  6. CentOS 7 配置 Nginx 正向代理 http、https 最详解

    手头项目中有使用到 nginx,因为使用的三方云服务器,想上外网需要购买外网IP的,可是有些需要用到外网却不常用的主机也挂个外网IP有点浪费了,便想使用nginx的反向代理来实现多台内网服务器使用一台 ...

  7. Java代理模式之Cglib代理

    Cglib代理,也叫做子类代理.在内存中构建一个子类对象从而实现对目标对象功能的扩展. CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类.不鼓励直接使用ASM,因 ...

  8. 代理模式之Cglib代理

    Cglib代理,也叫做子类代理.在内存中构建一个子类对象从而实现对目标对象功能的扩展. l  JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口.如果想代理没有实现接口的类,就可 ...

  9. Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解

    废话不多说,本文将会层层深入给大家讲解如何动态的生成一个完整的界面. 本文内容: Java代码中动态生成View Java代码中动态设置View的位置,以及其他的属性 LayoutParams详解 一 ...

  10. Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解

    1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...

随机推荐

  1. 如何实现CentOS服务器的扩容??

    Linux的硬盘识别: 一般使用"fdisk -l"命令可以列出系统中当前连接的硬盘 设备和分区信息.新硬盘没有分区信息,则只显示硬盘大小信息. 1.关闭服务器加上新硬盘 2.启动 ...

  2. python面向对象基础-属性/方法

  3. 【IMPDP】ORA-31655

    出现ora-31655错误的情况是因为不是同一个schema,导致的问题产生 解决的方法; 在导入语句最后添加上remap_schema=old:new 着old是原schema,也就是导出的用户名, ...

  4. 面试时通过volatile关键字,全面展示线程内存模型的能力

    面试时,面试官经常会通过volatile关键字来考核候选人在多线程方面的能力,一旦被问题此类问题,大家可以通过如下的步骤全面这方面的能力.     1 首先通过内存模型说明volatile关键字的作用 ...

  5. DOCKER 安装步骤-最靠谱的笔记

    一.系统环境规划 服务器名 项目名称 docker 操作系统 CentOS Linux release 7.1.1503 (Core) Docker 版本 17.03.2-ce   二.Docker ...

  6. 手机QQ空间自动点赞登录

    学以致用~使用 Appium 模拟人类操控手机行为 V2.0在手机上运行,目前实现以下功能: 1.小黑屋模式,一分钟内给好友发100条消息然后进了好友的小黑屋 2.定时发消息提醒对象多喝热水~ 3.对 ...

  7. MySQL 5.6.35 索引优化导致的死锁案例解析

    一.背景 随着公司业务的发展,商品库存从商品中心独立出来成为一个独立的系统,承接主站商品库存校验.订单库存扣减.售后库存释放等业务.在上线之前我们对于核心接口进行了压测,压测过程中出现了 MySQL ...

  8. 目标检测的评价指标(TP、TN、FP、FN、Precision、Recall、IoU、mIoU、AP、mAP)

    1. TP TN FP FN ​ GroundTruth 预测结果 TP(True Positives): 真的正样本 = [正样本 被正确分为 正样本] TN(True Negatives): 真的 ...

  9. Linux定时任务crontab通俗易懂简单扼要地解析

    1.安装crontab 在配置好yum源的情况下,直接执行如下命令即可: yum install crontab 2.查看当前环境上已经有的定时任务有哪些? 执行如下命令即可 crontab -l 如 ...

  10. 每月一更的《HelloGitHub》第 58 期,来啦!

    HelloGitHub 分享 GitHub 上有趣.入门级的开源项目.欢迎大家: 贡献代码 宣传你觉得优秀的项目 Star 项目️ 本月刊是每月 28 号更新,再见月刊就是年后了.在这里提前祝大家:新 ...