代理定义:
代理(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. PHP jquer网页打印插件 PrintArea

    <!DOCTYPE html> <head> <meta charset="utf-8"> <meta http-equiv=" ...

  2. 【Web】CSS实现鼠标悬停实现显示与隐藏 特效

    鼠标悬停实现显示与隐藏特效 简单记录 - 慕课网 Web前端 步骤四:鼠标悬停实现显示与隐藏特效 初步掌握定位的基本使用,以及CSS选择器更高级的运用,完成一个网页中必会的鼠标经过隐藏显示特效. 实现 ...

  3. LeetCode637. 二叉树的层平均值

    题目 1 class Solution { 2 public: 3 vector<double>ans; 4 vector<double> averageOfLevels(Tr ...

  4. 攻防世界 - Crypto(一)

    base64: 根据题目base64可知编码方式,下载附件发现是一个txt文件,把内容用工具解码就彳亍了,即可得到flag, flag: cyberpeace{Welcome_to_new_World ...

  5. 数据分析 Pandas 简介和它的的数据结构

    本文主要讲Pandas 的Series和DataFrame 的相关属性和操作 1.Series的相关属性和操作# --Series是一种类似于一维数组的对象,只能存放一维数组!由以下两部分组成:# v ...

  6. 如何使用github搜索需要的开源项目

    按照项目名/仓库名搜索(大小写不敏感)in:name xxx按照README搜索(大小写不敏感)in:readme xxx按照description搜索(大小写不敏感)in:description x ...

  7. [XAML] 使用 XAML 格式化工具:XAML Styler

    1. XAML 的问题 刚入门 WPF/UWP 之类的 XAML 平台,首先会接触到 XAML 这一新事物.初学 XAML 时对它的印象可以归纳为一个词:一坨. 随着我在 XAML 平台上工作的时间越 ...

  8. cts project的创建修改和删除

    事务码:SPRO_ADMIN进入 项目管理界面,点击工具栏创建项目(F5),弹出对话框,输入项目名称,回车确定. 标题中输入项目的描述.点击保存.如图: 点击图片放大 注:要想此项目在CTS建立请求的 ...

  9. sap的内核升级,修补了源代码保护的方式

    众所周知,在SAP的内核位701或者之前的版本中,我们可以通过向源代码的中加入"*@#@@[SAP]"这样的代码,来实现对源代码的保护.但是在内核升级到721和以后的版本中,你会发 ...

  10. postgres模糊匹配大杀器

    ArteryBase-模糊匹配大杀器 问题背景 随着pg越来越强大,abase目前已经升级到5.0(postgresql10.4),目前abase5.0继承了全文检索插件(zhparser),使用全文 ...