代理定义:
代理(Proxy):是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象。
好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。

动态代理+静态代理+cglib代理 区别:

1、静态代理===>>>代理对象与目标对象要实现相同的接口或者是继承相同父类, 然后通过调用相同的方法来调用目标对象的方法

2、动态代理===>>>代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理。

3、cglib代理===>>>目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以使用以目标对象子类的方式类实现的Cglib代理。

静态代理总结:
1.优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展。
2.缺点 :因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护。

动态代理总结:
1.优点:代理对象,不需要实现接口,也叫做:JDK代理,接口代理。
2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)。

cglib代理总结:
1.优点:Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
2.缺点:Cglib原理是针对目标类生成一个子类,覆盖其中的所有方法,所以目标类和方法不能声明为final类型。

下面上代码:

(一)动态代理:

  1. package com.example.demo.test.dynamic.proxy;
  2.  
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.Method;
  5. import java.lang.reflect.Proxy;
  6. import lombok.Data;
  7.  
  8. /**
  9. * 创建动态代理对象
  10. * 动态代理不需要实现接口,但是需要指定接口类型
  11. */
  12. public class ProxyFactory {
  13.  
  14. //维护一个目标对象
  15. private Object target;
  16.  
  17. public ProxyFactory(Object target) {
  18. this.target = target;
  19. }
  20.  
  21. //给目标对象生成代理对象
  22. public Object getProxyInstance() {
  23.  
  24. System.out.println("==>>开始代理事务");
  25. return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
  26.  
  27. @Override
  28. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  29. return method.invoke(target, args);
  30. }
  31. }
  32. );
  33. }
  34.  
  35. }
  1. package com.example.demo.test.dynamic.proxy;
  2.  
  3. public interface IUserDao {
  4.  
  5. void save();
  6.  
  7. void delete();
  8.  
  9. void saveAndDelete();
  10. }
  1. package com.example.demo.test.dynamic.proxy;
  2.  
  3. public class UserDao implements IUserDao {
  4.  
  5. public void save() {
  6. System.out.println("====save");
  7. }
  8.  
  9. public void delete() {
  10. System.out.println("====delete");
  11. }
  12.  
  13. public void saveAndDelete() {
  14. save();
  15. delete();
  16. }
  17.  
  18. }

===>>>测试:

  1. package com.example.demo.test.dynamic.proxy;
  2.  
  3. /**
  4. * @date: 2020/12/11 19:55
  5. * @description:
  6. */
  7. public class Client {
  8.  
  9. public static void main(String[] args) {
  10. // 目标对象
  11. UserDao target = new UserDao();
  12. // class aop.UserDao
  13. System.out.println(target.getClass());
  14.  
  15. // 给目标对象,创建代理对象
  16. IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
  17. // class $Proxy0 内存中动态生成的代理对象
  18. System.out.println(proxy.getClass());
  19. System.out.println("=========================");
  20. proxy.save();
  21. proxy.delete();
  22. proxy.saveAndDelete();
  23. }
  24. }

(一)静态代理:

  1. package com.example.demo.test.proxy;
  2.  
  3. /**
  4. * 代理对象,静态代理
  5. */
  6. public class UserDaoProxy implements IUserDao{
  7.  
  8. //接收保存目标对象
  9. private IUserDao target;
  10.  
  11. public UserDaoProxy(IUserDao target) {
  12. this.target = target;
  13. }
  14.  
  15. public void save() {
  16. System.out.println("开始代理...");
  17. target.save();
  18. }
  19. }
  1. package com.example.demo.test.proxy;
  2.  
  3. /**
  4. * 接口
  5. */
  6. public interface IUserDao {
  7.  
  8. void save();
  9. }
  1. package com.example.demo.test.proxy;
  2.  
  3. /**
  4. * 接口实现 目标对象
  5. */
  6. public class UserDao implements IUserDao {
  7.  
  8. public void save() {
  9. System.out.println("----已经保存数据!----");
  10. }
  11.  
  12. }

===>>>测试:

  1. package com.example.demo.test.proxy;
  2.  
  3. /**
  4. * 测试类
  5. */
  6. public class AppTest {
  7.  
  8. public static void main(String[] args) {
  9. //目标对象
  10. UserDao target = new UserDao();
  11.  
  12. //代理对象,把目标对象传给代理对象,建立代理关系
  13. UserDaoProxy proxy = new UserDaoProxy(target);
  14.  
  15. proxy.save();//执行的是代理的方法
  16. }
  17. }

(一)cglib代理:

  1. package com.example.demo.test.cglib;
  2.  
  3. import com.example.demo.test.dynamic.proxy.UserDao;
  4. import net.sf.cglib.core.DebuggingClassWriter;
  5. import net.sf.cglib.proxy.Enhancer;
  6.  
  7. /**
  8. * @date: 2020/12/11 20:07
  9. * @description:
  10. */
  11. public class CglibClient {
  12.  
  13. public static void main(String[] args) {
  14.  
  15. CglibProxyFactory cglibProxy = new CglibProxyFactory();
  16. //jdk需要提供接口,cglib需要是非私有类,且不能处理final关键字修饰的方法
  17. Enhancer enhancer = new Enhancer();
  18. //设置父类
  19. enhancer.setSuperclass(UserDao.class);
  20. //设置回调对象
  21. enhancer.setCallback(cglibProxy);
  22.  
  23. UserDao proxy = (UserDao) enhancer.create();
  24. proxy.save();
  25. proxy.delete();
  26. proxy.saveAndDelete();
  27. }
  28. }
  1. package com.example.demo.test.cglib;
  2.  
  3. import net.sf.cglib.proxy.MethodInterceptor;
  4. import net.sf.cglib.proxy.MethodProxy;
  5.  
  6. import java.lang.reflect.Method;
  7.  
  8. /**
  9. * @author: 乔利强
  10. * @date: 2020/12/11 20:05
  11. * @description:
  12. */
  13. public class CglibProxyFactory implements MethodInterceptor {
  14.  
  15. public CglibProxyFactory() {
  16. }
  17.  
  18. /**
  19. * 1、代理对象;2、委托类方法;3、方法参数;4、代理方法的MethodProxy对象。
  20. *
  21. * @param obj
  22. * @param method
  23. * @param objects
  24. * @param methodProxy
  25. * @throws Throwable
  26. */
  27. @Override
  28. public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  29.  
  30. System.out.println("走代理方法......" + method.getName());
  31. return methodProxy.invokeSuper(obj, objects);
  32. }
  33. }

动态代理+静态代理+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. ES6+Webpack+Babel基本环境搭建

    ### 本文基本是流水文,记录学习中步骤,希望对看到的你有用,蟹蟹. 基本环境搭建 技术栈 Webpack ES6 Babel 开发环境 VS Code Node 搭建环境过程 新建项目文件夹

  2. redis简介与window安装:

    redis简介与window安装: 花开堪折直需折,莫待无花空折枝 Redis 概念:Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(ke ...

  3. JAVA_基础反射创建运行时类的对象

    通过反射去创建对应的运行时类的对象 newInstance():调用此方法,创建对应的运行时类的对象.内部调用的是空参的构造器. 要想此方法正常的创建运行时类的对象,要求: 1.运行时类必须提供空参构 ...

  4. Serverless 如何应对 K8s 在离线场景下的资源供给诉求

    本文整理自腾讯云云原生产品团队的专家产品经理韩沛在 Techo 开发者大会云原生专题的分享内容--Kubernetes 混部与弹性容器.本次分享主要分为三部分:基于 K8s 的应用混部.提升应用混部效 ...

  5. 树莓派-4WD智能小车操作小结

    树莓派-4WD智能小车操作小结 树莓派4B-4WD智能小车,双层结构,第一层结构为:小车扩展板(底层)+树莓派主板,通过铜柱隔离固定,小车扩展板相当于计算机的外设扩展板:上面一层为第二层,是三个舵机承 ...

  6. 【Flutter】可滚动组件之GridView

    前言 GridView可以构建一个二维网格列表.需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout).Sl ...

  7. java8新特性之stream流

    Stream 流是 Java 8 提供给开发者一套新的处理集合的API,他把我们将要处理的集合作为流,就像流水线一样,我们可以对其中的元素进行筛选,过滤,排序等中间操作,只不过这种操作更加简洁高效. ...

  8. python3.6安装教程

    Python代码要运行,必须要有Python解释器.Python3.x的版本是没有什么区别的,这里以3.6版本来演示安装的过程.这里只介绍Windows环境下的安装. 下载安装程序 Python官方的 ...

  9. 【Jboss】一台服务器上如何部署多个jboss

    一台服务器上如何部署多个jboss呢?直接把整个部署环境copy一份到相应的目录下? 这样只是前提,但是启动复制后的jboss就会发现,有很多端口被占用 3873,8080,8009,8443,808 ...

  10. go语言循环变量

    阅读go语言圣经第五章第六节介绍到了捕获迭代变量 package main import ( "fmt" ) func main() { var lis []func() for ...