详解:设计模式之-代理设计

分享一波:程序员赚外快-必看的巅峰干货

概念

通过代理控制对象的访问,可以详细访问某个对象的方法,在这个方法调用处理,或调用后处理(类似于AOP)。

代理设计模式应用场景:AOP、权限控制、事务

常见代理的分类有:静态代理,动态代理(JDK动态代理,Cglib等)

注意:本文所指的“代理”为设计模式中的“代理设计模式”,跟正向、反向代理并非一个概念,不要混淆。
静态代理

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

public interface IUserDao {
void save();
}

public class UserDao implements IUserDao {
public void save() {
System.out.println(“已经保存数据…”);
}
}

/**

  • 代理类
    */
    public class UserDaoProxy implements IUserDao {
    private IUserDao target;

    public UserDaoProxy(IUserDao iuserDao) {
    this.target = iuserDao;
    }

    public void save() {
    System.out.println(“开启事物…”);
    target.save();
    System.out.println(“关闭事物…”);
    }

}

静态代理需要每个被代理类都有一个代理类,因此代码量较多,实际开发中非必须情况尽量少用。
动态代理
JDK动态代理

1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下)

2)实现方式:

  1. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);

  2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});

  3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});

  4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

缺点:jdk动态代理,必须是面向接口,目标业务类必须实现接口

public class InvocationHandlerImpl implements InvocationHandler {

/** 目标代理对象 */
private Object target;public InvocationHandlerImpl(Object target) {this.target = target;
}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 反射执行方法Object invoke = method.invoke(target, args);return invoke;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException,IllegalAccessException, IllegalArgumentException, InvocationTargetException {// 被代理对象IUserDao userDao = new UserDao();InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);ClassLoader loader = userDao.getClass().getClassLoader();Class<?>[] interfaces = userDao.getClass().getInterfaces();// 主要装载器、一组接口及调用处理动态代理实例IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);newProxyInstance.save();
}

}

Cglib动态代理

原理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码

引入依赖:

org.apache.commons commons-lang3 3.8.1 cglib cglib 3.1

创建代理:

public class CglibProxy implements MethodInterceptor {

/** 代理对象 */
private Object target;public Object getInstance(Object target) {// 固定代码,创建访问对象this.target = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();
}public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {Object invoke = methodProxy.invoke(target, args);return invoke;
}public static void main(String[] args) {CglibProxy cglibProxy = new CglibProxy();UserDao userDao = (UserDao) cglibProxy.getInstance(new UserDao());userDao.save();
}

}

Cglib和jdk动态代理的区别

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

Spring中。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP

2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP

3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

JDK动态代理只能对实现了接口的类生成代理,而不能针对类 。

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法 。

因为是继承,所以该类或方法最好不要声明成final ,final可以阻止继承和多态。

分享一波:程序员赚外快-必看的巅峰干货

如果以上内容对你觉得有用,并想获取更多的赚钱方式和免费的技术教程

请关注微信公众号:HB荷包
在这里插入图片描述
一个能让你学习技术和赚钱方法的公众号,持续更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/537045.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【实时+排重】摆脱渠道统计刷量作弊行为

如今的渠道统计不仅要看精准度&#xff0c;更要看数据的真实性。 对App的推广业务而言&#xff0c;渠道监测和统计是必不可少的环节&#xff0c;不论以什么形式开展推广&#xff0c;终究都要具体落实到App的安装量、激活量等指标上。但在如今数据刷量和作假行为横行的背景下&am…

python清空idle的内容_Python IDLE清空窗口的实例

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":4,"count":4}]},"card":[{"des":"阿里技术人对外发布原创技术内容的最大平台&…

详解:设计模式之-单例设计模式

分享一波:程序员赚外快-必看的巅峰干货 前言 近期预计1-2周左右会更新设计模式专题文章。 单例设计模式&#xff1a;保证在一个JVM中&#xff0c;只能存在一个实例。 应用场景&#xff1a;Servlet&#xff0c;Spring IOC&#xff0c;线程池&#xff0c;连接池&#xff0c;S…

rabbitmq可靠性投递_阿里Java研发二面:了解RabbitMQ?说说RabbitMQ可靠性投递

上期写到高并发下RabbitMq消息中间件你应该介么玩今天给小伙伴说说&#xff01;有自己看法的也可以在评论区留言探讨&#xff0c;也可以转发关注下我以后会长期分享&#xff01;目录&#xff1a;确保消息发送到RabbitMQ服务器确保消息被正确的路由确保消息在队列正确地存储确保…

IBM发布Open Liberty 18.0.0.4,支持MicroProfile 2.1和反应性扩展框架

IBM在2018年第四季度发布的Open Liberty 18.0.0.4提供了对MicroProfile 2.1、反应性扩展框架和连接池指标的全面支持。根据发布说明&#xff1a;Open Liberty现在对JAX-RS 2.1进行了反应性扩展&#xff0c;这样你就可以使用来自Apache CXF和Jersey的提供程序。在ops方面&#x…

b700a怎么连蓝牙_233621蓝牙2.1无线音箱B700A小测

随着蓝牙技术的发展&#xff0c;使用蓝牙的相关产品也越来越多&#xff0c;各种蓝牙耳机、蓝牙键盘、蓝牙鼠标都让我们的外设摆脱了线材的束缚。小编之前也介绍过一款便携蓝牙音箱&#xff0c;也评测过一款蓝牙耳机&#xff0c;而今天拿到的是一款采用蓝牙2.1技术&#xff0c;造…

详解:设计模式之-适配器模式

分享一波:程序员赚外快-必看的巅峰干货 简介 在设计模式中&#xff0c;适配器模式有时候也称包装样式或者包装。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起&#xff0c;做法是将类自己的接口包裹在一个已存在的类中。 分类 …

excel 中编程:vba 入门

2019独角兽企业重金招聘Python工程师标准>>> 1. 打开编程环境&#xff1a; altF11 打开开发环境 注意需要启动宏&#xff0c;不然不能执行自定义的程序&#xff0c;保存后文件的后缀应该是&#xff1a;.xlsm 选择一个 sheet 或一个模块&#xff0c;右键查看代码&…

android 快传 源码_最新安卓仿茄子快传APP源码包括服务端源码Android开发快传类项目源码全套...

适使用范围&#xff1a; 安卓APP茄子快传源码 Android项目源码相似茄子快传的快传项目包括服务端运行环境&#xff1a; Android app源码详细&#xff1a;本项目是一个基于安卓的相似茄子快传的项目源码&#xff0c;包括安卓用户端源码&#xff0c;java的PC用户端和PHP 的web网…

详解:设计模式之-策略设计模式

分享一波:程序员赚外快-必看的巅峰干货 什么是策略模式 定义一系列的算法&#xff0c;并将每一个算法单独进行封装&#xff0c;而且使它们可以相互替换&#xff0c;从而达到传递不同参数而执行不同算法的结果。 策略模式让算法独立于使用它的客户而独立变化 策略模式应用场…

mysql decode语句_MySQL复制问题的分析

s这是学习笔记的第 2031 篇文章最近有个业务的MySQL复制问题还是比较多&#xff0c;做了事务降维之后&#xff0c;把一些敏感操作和线上环境隔离起来&#xff0c;整体的效果好了许多&#xff0c;不过今天在外面的时候&#xff0c;又收到一条报警短信&#xff0c;让我心里咯噔一…

jvm形象简介之一看就懂

分享一波:程序员赚外快-必看的巅峰干货 据 JVM 规范&#xff0c;JVM 内存结构共分为虚拟机栈、堆、方法区、程序计数器、本地方法栈五个部分。这里的java内存结构与前面所述的Java内存模型是两个概念&#xff0c;不可以混淆。 堆 java堆是java虚拟机所管理的内存中最大的一块…

MZOJ 1345 hero

一道宽搜模版题,可写错了两个地方的我只得了56(掩面痛哭) http://10.37.2.111/problem.php?id1345 先看看正确的 #include <bits/stdc.h> #define read read() #define up(i,l,r) for(int i l; i<r; i) using namespace std;int read {int x 0; char ch getchar()…

opencv拖动进度条_OpenCV GUI基本操作,回调函数,进度条,裁剪图像等-阿里云开发者社区...

代码为转载&#xff0c;出处找不到了&#xff0c;不贴了工具条进度条&#xff1a;// ConvertColor.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include #include #include #pragma comment(lib,"opencv_core2410d.lib")#pragma comment(lib…

区间DP初探 P1880 [NOI1995]石子合并

https://www.luogu.org/problemnew/show/P1880 区间dp,顾名思义,是以区间为阶段的一种线性dp的拓展 状态常定义为$f[i][j]$,表示区间[i,j]的某种解; 通常先枚举区间长度,再枚举左端点,最后枚举断点(k) 石子合并便是一道经典的区间dp #include <bits/stdc.h> #define read…

jvm详解 - 新生代与老年代

*************************************优雅的分割线 ********************************** 分享一波:程序员赚外快-必看的巅峰干货 Java 中的堆是 JVM 所管理的最大的一块内存空间&#xff0c;主要用于存放各种类的实例对象。 在 Java 中&#xff0c;堆被划分成两个不同的区…

pymysql建表_Python数据库操作,针对pymysql 和 MYSQL数据库

此文将以MYSQL数据库做为例子,pymysql库作为驱动进行学习安装MYSQL数据库与pymysql第三方库安装pymysql库不多做叙述安装navicat for mysql,此程序用来管理MYSQL数据库注意: 连接过程中可能会出现1251错误解决办法,在cmd命令下登录mysql后输入:ALTER USER rootlocalhost IDENTI…

从0到1使用VUE-CLI3开发实战(五):模块化VUEX及使用vuetify

小肆前几天发了一篇2019年Vue精品开源项目库的汇总&#xff0c;今天小肆要使用的是在UI组件中排行第三的Vuetify。vuetify介绍 Vuetify是一个渐进式的框架&#xff0c;完全根据Material Design规范开发&#xff0c;一共拥有80多个组件&#xff0c;对移动端支持非常好。 支持SSR…

详解垃圾回收算法

分享一波:程序员赚外快-必看的巅峰干货 标记清除算法 概念 该算法有两个阶段。 标记阶段&#xff1a;找到所有可访问的对象&#xff0c;做个标记。 清除阶段&#xff1a;遍历堆&#xff0c;把未被标记的对象回收 缺点&#xff1a;会产生碎片&#xff0c;不够连贯 应用场景…

智能情绪分析技术_石化缘推荐:炼化企业智能机器人巡检技术应用前景分析!...

本期内容由湖南天一奥星泵业有限公司冠名炼化企业智能机器人巡检技术应用前景分析王国彤1,孙秉才2,储胜利2,宋亚敏1(1.中国石油天然气股份有限公司大连石化分公司&#xff0c;辽宁省大连市&#xff1b;2.中国石油集团安全环保技术研究院有限公司&#xff0c;北京市)摘要&#x…