反射、静态代理、动态代理(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 ...
随机推荐
- css中设置背景图片适应屏幕
以body为例 body{ background: url(../img/jld.png) no-repeat center center fixed; -webkit-background-size ...
- chapter2 线性回归实现
1 导入包 import numpy as np 2 初始化模型参数 ### 初始化模型参数 def initialize_params(dims): w = np.zeros((dims, 1)) ...
- JavaIo流入门篇之字节流基本使用。
一 基本知识了解( 字节流, 字符流, byte,bit是啥?) /* java中字节流和字符流之前有接触过,但是一直没有深入的学习和了解. 今天带着几个问题,简单的使用字节流的基本操作. 1 什么 ...
- 微服务架构 | 11.1 整合 Seata AT 模式实现分布式事务
目录 前言 1. Seata 基础知识 1.1 Seata 的 AT 模式 1.2 Seata AT 模式的工作流程 1.3 Seata 服务端的存储模式 1.4 Seata 与 Spring Clo ...
- 如何高效地写 Form
工作少不了写"增删改查","增删改查"中的"增"和"改"都与 Form 有关,可以说:提升了 Form 的开发效率,就提 ...
- SSL证书,IIS7、IIS8,http自动跳转到HTTPS
安装"URL REWRITE2 " 伪静态模块,IIS7需要先确认是否安装 "URL REWRITE2 " 伪静态模块 , 如果您已经安装可以跳过 下载地址:h ...
- vue+element ui中select组件选择失效问题原因与解决方法
codejing 2020-07-10 09:13:31 652 收藏 分类专栏: Web Vue Element UI 版权 .当表单form赋完值后,如果后续又对form中某一属性值进行操作如 ...
- Java线程--CountDownLatch使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11867656.html Java线程--CountDownLatch使用, 代码里头有详细注释 ...
- MySQL 主从复制与读写分离 (超详细图文并茂小白闭着眼睛都会做)
MySQL 主从复制与读写分离 1.什么是读写分离 2.为什么要读写分离 3.什么时候要读写分离 4.主从复制与读写分离 5.mysql支持的复制类型 6.主从复制的工作过程 7.MySQL主从复制延 ...
- Msi.h causes compilation error in vs2010
创建一个Win32 Console工程ReadFromMSM,什么都不需要做. 在ReadFromMSM.cpp文件中引入头文件: #include <msi.h> 编译,会发现有成堆的错 ...