【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.hqwc.cn/news/312051.html

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

相关文章

STC8H系列单片机入门教程之NVC系列语音播报模块(九)

一、模块简述 ● 模组支持3.3V和5V单片机供电系统 ● 标准2.54MM间距排针与外部连接 ● 支持喇叭0.5W/8欧 ● 适合用于超声波距离、电子秤重量、时钟时间、温度、球赛比分等语音播报 二、引脚说明 序号 名称 说明 1 VCC 电源正&#xff08;3.3V-5V&#…

spring核心与思想

spring核心与思想 Spring 是什么&#xff1f;什么是容器&#xff1f;什么是 IoC&#xff1f;传统程序开发传统程序开发的缺陷解决传统开发中的缺陷控制反转式程序开发对⽐总结规律 理解 Spring IoCDI 概念说明 Spring 是什么&#xff1f; Spring 指的是 Spring Framework&…

炫斗H5小游戏

欢迎来到程序小院 炫斗 玩法&#xff1a;点击左右拳头攻击两侧敌人&#xff0c;宠物出现时能为你吸收少量伤害&#xff0c; 敌方英雄出现时需要多次攻击才能消灭&#xff0c;在60秒内挑战最高分吧^^。开始游戏https://www.ormcc.com/play/gameStart/234 html <div id"…

龙年红包封面来了,可以领取了。

今天是周六&#xff0c;后天就是元旦了&#xff0c;过完元旦就快要过年了&#xff0c;大家又要开始发红包和收红包了。下面分享一个腾讯的龙年红包封面给大家&#xff0c;可以免费领取&#xff0c;大家可以看下我领取的发红包的效果图&#xff0c;如下所示。 下面这个是红包打开…

条款13:以对象管理资源

文章目录 没有管理的情况解决办法之unique_ptr智能指针解决办法之shared_ptr智能指针总结 没有管理的情况 资源是指一旦你使用完它&#xff0c;就需要返回系统的东西。 class Investment { ... }; // 投资类型层次结构的基类 Investment* createInvestment(); // 工厂函数&…

mount -a 出错任然重启问题

问题来源 在磁盘分区挂载过后&#xff0c;为了创建的新分区的能够永久挂载&#xff0c;我们常常会在/etc/fstab下写下配置文件&#xff0c;使其永久挂载。但是该配置一旦写错&#xff0c;就面临这死机问题&#xff0c;为此&#xff0c;以下操作针对该问题进行 解决方案&#x…

vue 项目 添加 页面上方 NProgress进度条

NProgress官网和Github地址 路由 跳转时 页面上方 和 右上角 会有一个加载进度 安装 使用npm安装 npm install --save nprogress 基本用法 main.js 引入 import NProgress from “nprogress”; import “nprogress/nprogress.css”; 开关和关闭 start()开启NProgress进度条d…

「GPT」G、P、T分别是啥意思?

G意为Generative &#xff1a;生成式 比如&#xff0c;生成式的分类器&#xff08;模型&#xff09;包括---- generative classifiers: naive Bayes classifier and linear discriminant analysis 与之对应的为判别式----- discriminative model: logistic regression P意为…

SSM房屋租赁系统----计算机毕业设计

项目介绍 房屋租赁系统&#xff0c;基于 Spring5.x 的实战项目&#xff0c;此项目非Maven项目。 前台系统主要功能包括房源列表展示、房源详细信息展示、根据房源特征进行搜索&#xff0c;包括&#xff1a;房型、小区名;以及房源的预订功能。 后台管理&#xff1a; 用户信息管…

20231228在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单前置摄像头ov13850

20231228在Firefly的AIO-3399J开发板的Android11的挖掘机的DTS配置单前置摄像头ov13850 2023/12/28 10:42 【碰到一个很神奇的问题】&#xff1a; 昨天晚上前置摄像头怎么也点不亮&#xff01;改了巨多的地方&#xff01;晚上睡觉之前把开发板彻底断电了&#xff01;今天开电脑…

揭秘HTTP与HTTPS:保障安全的网页传输协议之争

目录 1、前言 2、HTTP与HTTPS的概念及区别 2.1 HTTP的定义与特点 2.2 HTTPS的定义与特点 2.3 HTTP与HTTPS的区别 3、HTTP的工作原理及安全隐患 3.1 HTTP的工作流程 3.2 HTTP的安全隐患 4、HTTPS的工作原理及优势 4.1 HTTPS的工作流程 4.2 HTTPS的加密算法 4.3 HTTP…

Hive生产调优介绍

1.Fetch抓取 Fetch抓取是指&#xff0c;Hive中对某些情况的查询可以不必使用MapReduce计算。例如&#xff1a;SELECT * FROM employees;在这种情况下&#xff0c;Hive可以简单地读取employee对应的存储目录下的文件&#xff0c;然后输出查询结果到控制台。 在hive-default.xml…