反射、静态代理、动态代理(jdk、cglib)
一、反射
反射在之前的文章中详细的解释过了,简单概括就是:可以动态的获取到一个类内部的所有的信息,动态的去创建对象和使用对象以及可以操作对象的属性和方法。
二、代理
首先解释一下代理:使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法。
三、静态代理
静态代理:被代理对象和代理对象要实现同一套接口且代理对象内部要包含被代理对象,被代理对象覆盖重写接口方法,在方法内部加上实际业务上的增强。
代码目录
代码演示
//公共接口
public interface ZhangSanInterface {
//定义一个吃饭的抽象方法
void eat();
} //张三类
public class ZhangSan implements ZhangSanInterface {
@Override
public void eat() {
System.out.println("吃饭。。。"); //实现方法体
}
} //张三代理类
public class ZhangSanProxy implements ZhangSanInterface{ private ZhangSanInterface zhangSanInterface; public ZhangSanProxy(ZhangSanInterface zhangSanInterface) {
this.zhangSanInterface = zhangSanInterface;
} @Override
public void eat() {
System.out.println("饭前洗手。。"); //方法前增强
zhangSanInterface.eat();
System.out.println("饭后洗碗。。"); //方法后增强
}
} //测试类
public class Main01 {
public static void main(String[] args) {
ZhangSanProxy proxy = new ZhangSanProxy(new ZhangSan()); //代理对象中传入张三对象
proxy.eat();
}
}
总结:静态代理不需要使用反射机制就能够实现,但是也存在了很明显的缺陷,如果想要在加一些其他的被代理类,必须要修改代码,不符合开闭原则(对外扩展开放,对内修改关闭),扩展性差、维护性差。
四、动态代理
动态代理:在程序的执行时(动态),使用jdk的反射机制,创建对象的能力,创建的是代理类的对象,而不用我们自己创建类文件。
1、JDK动态代理
使用java反射包中的类和接口实现动态代理的功能。 反射包 java.lang.reflect,里面有三个类:InvocationHandler、Method、Proxy
1) InvocationHandler接口(调用处理器) :就-一个方法invoke ( )
invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能就写在invoke ()方法中。
代理类完成的功能:
1.调用目标方法,执行目标方法的功能
2.功能增强,在目标方法调用时,增加功能。
方法原型:
参数: object proxy :jdk创建的代理对象,无需赋值。
Method method: 目标类中的方法,jdk提供me thod对象的
object[] args: 目 标类中方法的参数,jdk提供的 。
public object invoke (object proxy, Method method, Object[] args)
InvocationHandler接口:表示你的代理要千什么。
怎么用: 1.创建类实现接口Invocati onHandler
2.重写invoke()方法,把原来静态代理中代理类要完成的功能,写在这。
2) Method类:表示方法的,确切 的说就是目标类中的方法.
作用:邇过Method可以执行某个目标类的方法,Method. invoke() ;
method. invoke(目标对象,方法的参数)
3) Proxy类: 核心的对象,创建代理对象。之前创建对象都是new类的构造方法(),现在我们是使用Proxy类的方法,代替new的使用。
方法:静态方法 newProxyInstance ()
作用是:创建代理对象, 等同于静态代理中的 代理类 proxy = new 代理类() ;
参数:
1. ClassLoader loader 类加载器,负责向内存中加载对象的。使用反射获取对象的ClassLoader类a,a. getCalss () .getClassLoader(),目标对象的类加载器。
2. Class<?>[] interfaces:接口,目标对象实现的接口,也是反射获取的。
3. InvocationHandler h :我们自己写的,代理类要完成的功能。
返回值:newProxyInstance () 的返回值就是代理对象。
实现动态代理的步骤
1.创建接口,定义目标类要完成的功能
2.创建目标类实现接口
3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
1.调用目标方法
2.增强功能
4.使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。
代码目录
代码展示
//目标接口
public interface Target {
void eat();
} //目标类
public class TargetImpl implements Target {
@Override
public void eat() {
System.out.println("吃饭饭。。");
}
} //必须实现InvocationHandler接口,完成动态代理要做的功能(1.调用目标方法 2.功能增强)
public class MyHandler implements InvocationHandler { private Object taget; public MyHandler(Object taget) {
this.taget = taget;
} //动态代理:对象是活动的,不是固定的,需要传进来
//传入是谁,就给谁创建代理。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("洗手手。。");
Object invoke = method.invoke(taget, args);//执行目标方法
System.out.println("洗碗碗。。");
return null;
}
} //主函数
public class Main02 {
public static void main(String[] args) {
//1、创建目标对象
Target taget = new TargetImpl(); //2、创建InvocationHandler对象
InvocationHandler handler = new MyHandler(taget); //3、创建代理对象
Target proxy = (Target) Proxy.newProxyInstance(
taget.getClass().getClassLoader(),
taget.getClass().getInterfaces(),
handler);
//4、通过代理执行方法
proxy.eat();
}
}
2、CGLIB动态代理
cglib是第三方的工具类,创建代理对象。cglib原理是继承,通过继承目标类,创建它的子类,在子类中重写重写父类中同名的方法,实现功能修改/增强。cglib动态代理要求目标类能够被继承。
目录展示
代码展示
//目标类
public class Target {
public void eat(){
System.out.println("吃饭饭。。");
}
} //实现MethodInterceptor接口
public class CglibProxy implements MethodInterceptor {
private Object target; public CglibProxy(Object target) {
this.target = target;
} /**
* @param proxy 代理对象引用
* @param method 被代理对象的方法的描述引用
* @param objects 方法的参数
* @param methodProxy 代理对象的 对目标对象的方法的描述
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("洗手手。。");
method.invoke(target,objects);
System.out.println("洗碗碗。。");
return null;
}
} /主方法测试
public class Main03 {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy(new Target());
Target target = (Target) Enhancer.create(Target.class, cglibProxy);
target.eat();
}
}
反射、静态代理、动态代理(jdk、cglib)的更多相关文章
- 静态代理,动态代理,Cglib代理详解
一.静态代理 新建一个接口 定义一个玩家方法: package com."".proxy.staticc; public interface Iplayer { public vo ...
- 【SSH系列】静态代理&&动态代理
从设计模式说起 代理模式是二十三中设计模式中的一种,代理模式就是指由一个代理主题来操作真实的主题,真实的主题执行具体的业务操作,而代理主题负责其她相关业务,简而言之,代理模式可以由以下三个部分组成: ...
- 8、Spring教程之静态代理/动态代理
为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象 ...
- 轻松理解 Java 静态代理/动态代理
目录 什么是代理模式 定义 代理模式的主要角色 优点 缺点 静态代理 动态代理 JDK原生动态代理 例子 分析 小结 CGLIB动态代理 例子 分析 final类型 其他方案 尾声 理解Java动态代 ...
- Java的反射机制和动态代理
介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原 ...
- java静态和动态代理原理
一.代理概念 为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代.代理类负责请求的预处理.过滤.将请求分派给委托类 ...
- java反射机制与动态代理
在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...
- Java反射机制以及动态代理
Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...
- Java 的静态代理 动态代理(JDK和cglib)
转载:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是 ...
- Spring -07 -AOP [面向切面编程] - 使用注解@+ AspectJ 方式实现环绕/前/后等通知 -超简洁 --静态代理/动态代理{JDK/cglib}
1.spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解;使用注解来取代配置文件.1.1 引入xmlns:context ,指定扫描范围 <context:comp ...
随机推荐
- 怎么重载网卡?ip修改 HHS服务器
目录 一:目录结构知识详述 1.网卡配置文件 2,ip修改 3.重载网卡信息 4.关闭网络管理器(因为已经有了network)所有要关闭NetworkManager不然会发生冲突 5.判断SSH服务是 ...
- Gc如何判断对象可以被回收?
Gc如何判断对象可以被回收? 1 引用计数器 引用计数法的算法思路:给对象增加一个引用计数器,每当对象增加一个引用计数器+1,失去一个引用-1,所以当计数器是0的时候对象就没有引用了,就会被认为可回收 ...
- 【Vue源码学习】依赖收集
前面我们学习了vue的响应式原理,我们知道了vue2底层是通过Object.defineProperty来实现数据响应式的,但是单有这个还不够,我们在data中定义的数据可能没有用于模版渲染,修改这些 ...
- JavaScript之ES6常用新特性
参考:https://www.jianshu.com/p/ac1787f6c50f 变量声明:const 与 let const:常量,必须初始化值 let:变量 格式:const 变量A = & ...
- PostgreSQL逻辑订阅
测试环境:PostgreSQL 13.2 1.逻辑订阅简介 由于物理复制只能做到这个集群的复制,不能正对某个对象(表)进行复制,且物理复制的备库只能读,不能写.相反,逻辑订阅同时支持主备库读写,且可以 ...
- HowToDoInJava Spring 教程·翻译完成
原文:HowToDoInJava 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. ApacheCN 学习资源 目录 Spring 5 Spr ...
- Azure MFA 守护你的账户安全
一,引言 MFA 又名 "多因素身份认证",指用户在登录的时候提示输入其他形式的标识.如果只使用密码对用户进行身份验证,是特别不安全的,尤其是在密码泄露的情况下.为了提高安全性,启 ...
- Nginx 配置 HTTPS 服务器
Nginx 配置 HTTPS 服务器 Chrome 浏览器地址栏标志着 HTTPS 的绿色小锁头从心理层面上可以给用户专业安全的心理暗示,本文简单总结一下如何在 Nginx 配置 HTTPS 服务器, ...
- UITabBarController的基本使用
- 学习jsp篇:jsp简单实例之一注册
编程环境:IDEA,Tomcat ,JavaEE 实例一.注册 1.先在IDEA建一个web工程(不懂的可以在网上搜,一大堆..)ServletTest,在工程目录下的web目录建一个文件夹regis ...