【javaSE】代理并不难

代理:

代理模式最主要的就是在不改变原来代码(就是目标对象)的情况下实现功能的增强

在学习AOP之前先了解代理,代理有两种:一种是动态代理,一类是静态代理。

静态代理

        相当于是自己写了一个代理类,在调用的时候调用的是代理类,代理类中的处理还是原生的处理逻辑,不过在前后添加上需要增强功能的代码。(类似继承实现的)

缺点:需要为每一个被代理的对象都创建一个代理类。

静态代理实现:

1.创建接口

public interface Target {public abstract String getExe();
}

2.实现目标对象

public class MyTarget implements Target {@Overridepublic String getExe() {System.out.println("执行ing.....");return "ok";}
}

3.实现代理对象

package 反射;public class Proxy implements Target{MyTarget myTarget;public Proxy(MyTarget myTarget) {this.myTarget = myTarget;}@Overridepublic String getExe() {System.out.println("权限检查");String res= myTarget.getExe();System.out.println("日志打印");return res;}
}

4.测试代码

package 反射;public class demo1 {public static void main(String[] args) {MyTarget myTarget=new MyTarget();Proxy proxy = new Proxy(myTarget);proxy.getExe();}}

 

动态代理

动态代理模式最大的优势就是不用自己去写一个代理对象,它的代理对象会在java文件编译的时候,通过Java反射去创建的。所以减少了程序员的工作。动态代理的实现有两种方式,现在来介绍一下(基于接口实现)

jdk代理

1.创建接口

package com.aqiuo.jdk;public interface UserDao {public void addUser();public void deleteUser();
}

2.创建实现类

package 代理;public class UserServiceImpl implements UserService{public void addUser(){System.out.println("添加用户");}public void delUser(){System.out.println("删除用户");}}

3.编写切面类

package 代理;public class Aspect {public void admission(){System.out.println("权限检查");}public void log(){System.out.println("日志打印");}
}

4.编写代理类

package 代理;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class JdkProxy implements InvocationHandler {//用Object型才能动态代理Object object;public Object createInstance(Object object){this.object=object;Class[] clazz = object.getClass().getInterfaces();ClassLoader classLoader=JdkProxy.class.getClassLoader();return Proxy.newProxyInstance(classLoader,clazz,this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Aspect aspect=new Aspect();aspect.admission();Object res= method.invoke(object,args);aspect.log();return res;}
}

5.测试:

public class Test {public static void main(String[] args) {JdkProxy jdkProxy =new JdkProxy();UserService userService=new UserServiceImpl();UserService proxy= (UserService) jdkProxy.createInstance(userService);proxy.addUser();;proxy.delUser();}
}

/**JDK代理有一定局限性,使用动态代理的对象必须实现一个或多个接口,如果要对没有实现接口的类进行代理,可以用CGLIB代理

CGLIB代理

CGLIB是一个高性能的开源代码生成包,采用非常底层的字节码技术,对指定的目标类生成一个子类,并对子类增强,已经在Spring中集成

导包

<dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.2.2</version>
</dependency>

 MethodInterceptor拦截器
cglib的实现最重要的就是去实现这个MethodInterceptor接口来完成,就像jdk时候的InvocationHandler一样

package com.aqiuo.cglib;
//被代理的类
public class UserDao {public void addUser() {// TODO Auto-generated method stubSystem.out.println("添加用户");}public void deleteUser() {// TODO Auto-generated method stubSystem.out.println("删除用户");}}

 实现代理类

//代理类
package com.aqiuo.cglib;import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import com.aqiuo.Aspect.MyAspect;public class CglibProxy implements MethodInterceptor {//代理方法public Object createProxy(Object target) {//创建一个动态类对象Enhancer enhancer=new Enhancer();//确定要增强的类,设置为她的父类enhancer.setSuperclass(target.getClass());//添加回调函数enhancer.setCallback(this);//返回创建的代理类return enhancer.create();}/*** ProxyCGlib根据指定的父类,生成代理对象* method拦截的方法* args拦截方法的参数数组* methodProxy方法的代理对象,用来执行父类方法*/@Overridepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {//创建切面类对象MyAspect myAspect=new MyAspect();//前增强myAspect.check_permissions();//目标方法执行Object object=methodProxy.invokeSuper( proxy, args);//后增强myAspect.log();return object;}}

        cglib的原理就是在运行的时候,cglib会自动去生成一个子类,在子类里面去完成增强操作(就是拦截器里面),这里我们来验证cglib就用保存它的子类来查验,也就是将它自动生成的类放在一个指定路径下去看。 


//测试类
package com.aqiuo.cglib;public class CglibTest {public static void main(String[] args) {UserDao userDao=new UserDao();CglibProxy proxy=new CglibProxy();UserDao userDao2=(UserDao) proxy.createProxy(userDao);userDao2.addUser();userDao2.deleteUser();}}

cglib动态代理原理:
①创建拦截器:继承MethodInterceptor的 intercepter的类,在拦截器中重写intercerpt( )方法,就是增强+目标对象的方法调用,返回拦截器

②在测试这边创建一个类似proxy的子类对象enhancer,然后设置这个代理对象的类型(setSuperclass(目标对象的类型.class完成))

③创建一个拦截器,enhancer通过去设置回调函数(setCallback(拦截器))

④创建代理对象enhancer.create(),代理对象的类型要和目标对象一致哈,然后通过代理对象去完成方法的调用

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

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

相关文章

SAP-PP:Phantom Assembly 虚拟装配 概念理解

文章目录 前言一、Phantom assembly 是什么&#xff1f;二、举例总结 前言 最近在学习PP的过程中遇到一个校验增强&#xff0c;系统中将对生产订单的组件预留进行校验&#xff0c;是否消耗正常。 那么就遇到BOM中设定了虚拟装配件的标识预留&#xff0c;其是不消耗数量的&…

力扣(leetcode)第257题二叉树的所有路径(Python)

257.二叉树的所有路径 题目链接&#xff1a;257.二叉树的所有路径 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5] 输出…

win10和win11上解决乱码的一个优点偏门的方法,不算很完美

左下角搜索控制面板&#xff0c;进入控制面板之后&#xff0c;点击时钟和区域下面的更改日期、时间或数字格式 点击顶上的“管理”选项&#xff0c;然后找到更改系统区域设置&#xff0c;把下方的Beta版&#xff1a;使用Unicode UTF-8提供全球语言支持&#xff08;U&#xff…

视频批量转码:一键转换多个视频mp4格式到FLV视频

在数字媒体时代&#xff0c;视频格式的多样性给处理工作带来了诸多不便。满足不同的播放需求&#xff0c;经常要视频从一种格式转换为另一种格式。其中&#xff0c;将mp4格式转换为FLV格式的需求很常见。现在一起来看下云炫AI智剪如何高效的将视频批量转码方法&#xff0c;一键…

[Angular] 笔记 21:@ViewChild

chatgpt: 在 Angular 中&#xff0c;ViewChild 是一个装饰器&#xff0c;用于在组件类中获取对模板中子元素、指令或组件的引用。它允许你在组件类中访问模板中的特定元素&#xff0c;以便可以直接操作或与其交互。 例如&#xff0c;如果你在模板中有一个子组件或一个具有本地…

\r\n和缓冲区/进度条小程序

一 前置知识 带有\n就会立马刷新缓冲区(因为显示器是行刷新)&#xff0c;\r不会刷新缓冲区 刷新的2个场景: 1 ~fflush 缓冲区中存在\r或\n --> \r fflush --> 不换行的\n) 2 ~ 文件关闭自动刷新缓冲区 倒计时小程序0-9 %-d是左对齐,%d是右对齐 倒计时小程序0-99 …

复试 || 就业day05(2023.12.31)算法篇

文章目录 前言找不同最长回文串找到所有数组中消失的数字下一个更大元素 I键盘行 前言 &#x1f4ab;你好&#xff0c;我是辰chen&#xff0c;本文旨在准备考研复试或就业 &#x1f4ab;文章题目大多来自于 leetcode&#xff0c;当然也可能来自洛谷或其他刷题平台 &#x1f4ab…

在Go中使用Goroutines和Channels发送电子邮件

学习如何使用Goroutines和Channels在Go中发送电子邮件 在现代软件开发的世界中&#xff0c;通信是一个关键元素。发送电子邮件是各种目的的常见实践&#xff0c;例如用户通知、报告等。Go是一种静态类型和编译语言&#xff0c;为处理此类任务提供了高效和并发的方式。在本文中&…

pycharm配置pyqt5的ui文件转py文件的小工具

在PyCharm中配置 PyQt5 的 .ui 文件转 .py 文件的小工具其实是配置一个外部工具&#xff0c;以便可以直接在 IDE 中通过单击按钮来完成这个转换。你需要使用 pyuic5 命令&#xff0c;它是 PyQt5 的工具集之一&#xff0c;用于将 .ui 文件&#xff08;用 Qt Designer 创建的&…

BED 文件格式 chip-seq m6a数据可视化会用到

General usage — bedtools 2.31.0 documentationhttps://bedtools.readthedocs.io/en/latest/content/general-usage.html BED格式&#xff08;Browser Extensible Data format&#xff09;是一种在生物信息学中广泛使用的文本文件格式&#xff0c;用于描述基因组上的特征和…

消息队列考点梳理 + 高频面试题

你好&#xff0c;本文我将和你一起梳理面试中消息队列的高频考点&#xff0c;做到温故知新。 面试中如何考察消息队列 消息队列作为日常开发中应用最高频的基础组件之一&#xff0c;相关的问题自然也是面试中的常客。 在面试中对消息队列的考察方式&#xff0c;主要包括两种…

机器人中的数值优化之线性共轭梯度法

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文ppt来自深蓝学院《机器人中的数值优化》 目录 1.无约束优化方法对比 2.Hessian-vec product 3.线性共轭梯度方法的步长​编辑 4.共轭梯度…

7.10非递减子序列(LC491-M)

算法&#xff1a; 在90.子集II (opens new window)中我们是通过排序&#xff0c;再去重来达到去重的目的。 而本题求自增子序列&#xff0c;是不能对原数组进行排序的&#xff0c;排完序的数组都是自增子序列了。 肯定还是回溯算法。 画树&#xff1a; 树里面其实有两个注意…

[python]python利用pyaudio录制系统声音没有立体声混音怎么录制系统音频

当电脑没有立体声混音导致Python写代码无法使用pyaudio进行录制系统声音怎么办&#xff1f;查阅资料和安装驱动等方法都不行&#xff0c;难道没办法了吗&#xff1f;那为什么电脑其他软件可以做到呢&#xff1f;因此研究了一下pyaudio在没有立体声混音情况下确实无法录制声音&a…

SpringBoot发布项目到docker

Dockerfile FROM openjdk:11 # 作者 MAINTAINER chenxiaodong<2774398338qq.com># 安装 vim # RUN yum -y install vim# 环境变量 # 进入容器后的默认工作目录 ENV WORKPATH /usr/local/webapp ENV EXECFILE Docker2Application-0.0.1-SNAPSHOT.jarRUN mkdir -p $WORKPA…

Android Matrix画布Canvas旋转Rotate,Kotlin

Android Matrix画布Canvas旋转Rotate&#xff0c;Kotlin private fun f1() {val originBmp BitmapFactory.decodeResource(resources, R.mipmap.pic).copy(Bitmap.Config.ARGB_8888, true)val newBmp Bitmap.createBitmap(originBmp.width, originBmp.height, Bitmap.Config.…

hibernate 使用注解+拦截器实现自动开启、关闭session,提交、回滚事务

hibernate 使用注解+注解拦截器实现自动开启、关闭session,开启、提交、回滚事务 项目为springboot项目 ,springboot版本为:2.5.11, hiernate-core5.4.3 版本。spring-xxx 等为5.3.17版本 注意:在spring-xxx4.x版本+ hiernate-core5.x.x版本中,hibernate的配置 true是有效的…

软件开发新手用哪个IDE比较好?软件开发最好的IDE都在这!

目录 IDES 的优点 最佳编程 IDE 列表 Java 开发的流行集成开发环境 JetBrains 的 IntelliJ IDEA NetBeans 适用于 C/ C、C# 编程语言的最佳 IDE Visual Studio 和 Visual Studio 代码 Eclipse PHP 开发的最佳 IDE PHPStorm Sublime Text Atom JavaScript 的顶级 I…

局域网下的ROS多机通信

文章目录 一、通用控制模式二、网络连接三、软件设置3.1 ROS主机的bashrc文件3.2 ROS从机的bashrc文件3.3 注意事项四、远程控制4.1 SSH4.2 VNC五、具体操作流程安装ssh网络静态ip设置配置文件修改ssh登录多机通信文件配置参考

Python:正则表达式速通,码上上手!

1前言 正则表达式&#xff08;Regular Expression&#xff09;是一种用来描述字符串模式的表达式。它是一种强大的文本匹配工具&#xff0c;可以用来搜索、替换和提取符合特定模式的文本。 正则表达式由普通字符&#xff08;例如字母、数字、符号等&#xff09;和元字符&#…