java 编程基础 Class对象 反射:动态代理 和AOP:java.lang.reflect.Proxy:(Proxy.newProxyInstance(newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h))
为什么我们使用动态代理
Proxy类的使用规则
- static Class getProxyClass(ClassLoader loader, Class... interfaces): 创建一个动态代理类所对应的 Class对象,该代理类将实现interfaces 所指定的多个接口。第一个 ClassLoader 参数指定生成动态代理类的类加载器。(已过时)
- static Object newProxyInstance(ClassLoader loader,Class[] interfaces, InvocationHandler h): 直接创建一个动态代理对象,代理对象的实现类实现了 interfaces 指定的系列接口 ,执行代理对象的每一个方法时都会被替换执行InvocationHandler 对象的 invoke 方法。
package com.zmd.dynamicProxy; /**
* @ClassName Person
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/16.
*/
public interface Person {
void walk();
void sayHello(String name);
}
2,定义自定义的InvocationHandler 继承InvocationHandler:
package com.zmd.dynamicProxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* @ClassName MyInvocationHandler
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/16.
*/
public class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("=======正在执行方法:"+ method.getName());
if (objects != null) {
System.out.println("下面为传入的参数:");
for (Object arg : objects) {
System.out.println(arg);
}
} else {
System.out.println("没有传入任何的参数");
}
return null;
}
}
3,调用测试:
package com.zmd.dynamicProxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; /**
* @ClassName MyInvocationTest
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/16.
*/
public class MyInvocationTest {
public static void main(String[] args) {
InvocationHandler invocationHandler = new MyInvocationHandler();
Person person = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(),new Class[]{Person.class},invocationHandler);
person.walk();
person.sayHello("美女");
}
}

动态代理和AOP
package com.zmd.dynamicProxy.movieExample;
public interface Movie {
void play();
}
package com.zmd.dynamicProxy.movieExample;
public class ZhanlangMovie implements Movie {
@Override
public void play() {
System.out.println("战狼,播放中...");
}
}
3,创建代理用的工具类,比如放电影之前和之后要干的事儿
package com.zmd.dynamicProxy.movieExample;
public class MovieUtil {
//play之前的方法
public static void before(){
System.out.println("PLAY 之前....");
}
//play之前的方法
public static void after(){
System.out.println("PLAY 之后....");
}
}
4,创建自定义代理类继承InvocationHandler,使用工具类为要代理接口实现类增加效果
package com.zmd.dynamicProxy.movieExample; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler {
private Movie movie; public MyInvocationHandler(Movie movie) {
this.movie = movie;
} @Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
//先调用工具类的方法(加广告)
MovieUtil.before();
//执行被包装的类的方法
Object result = method.invoke(movie, args);
//再调用工具类的方法(还是广告)
MovieUtil.after();
return result; //被包装的类的方法返回什么,这里也返回什么
}
}
5,利用代理类封装功能类,传入被代理的接口实现类(电影),返回真正给用户的电影
package com.zmd.dynamicProxy.movieExample; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class MovieFactory {
public static Movie getFactoryMovie(Movie movie){
InvocationHandler movieInvocationHandler = new MyInvocationHandler(movie);
Movie movie1 = (Movie) Proxy.newProxyInstance(movie.getClass().getClassLoader(),movie.getClass().getInterfaces(),movieInvocationHandler);
return movie1;
}
}
6、使用代理类
package com.zmd.dynamicProxy.movieExample;
public class FactoryMovieTest {
public static void main(String[] args) {
Movie zhanlang = MovieFactory.getFactoryMovie(new ZhanlangMovie());
zhanlang.play();
}
}
PLAY 之前....
战狼,播放中...
PLAY 之后....
带泛型的代理,代理一切...
代理类 MyInvocationHandler.java
package com.zmd.dynamicProxy.movieExample; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* @ClassName MyInvocationHandler
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/17.
*/
public class MyInvocationHandler <T> implements InvocationHandler {
private T movie; public MyInvocationHandler(T movie) {
this.movie = movie;
} @Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
//先调用工具类的方法(加广告)
MovieUtil.before();
//执行被包装的类的方法
Object result = method.invoke(movie, args);
//再调用工具类的方法(还是广告)
MovieUtil.after();
return result;
}
}
使用代理做的包装工具类 MovieFactory.java
package com.zmd.dynamicProxy.movieExample; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; /**
* @ClassName MovieFactory
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/17.
*/
public class MovieFactory<T> {
public static <T> T getFactoryMovie(T movie){
InvocationHandler movieInvocationHandler = new MyInvocationHandler(movie);
T movie1 = (T) Proxy.newProxyInstance(movie.getClass().getClassLoader(),movie.getClass().getInterfaces(),movieInvocationHandler);
return movie1;
}
}
测试使用
音乐接口和实现类
package com.zmd.dynamicProxy.movieExample;
public interface Music {
void play();
}
package com.zmd.dynamicProxy.movieExample;
public class YueLiangZhiShang implements Music {
@Override
public void play() {
System.out.println("我在遥望,月亮之上...");
}
}
测试类
package com.zmd.dynamicProxy.movieExample; /**
* @ClassName FactoryMovieTest
* @projectName: object1
* @author: Zhangmingda
* @description: XXX
* date: 2021/5/17.
*/
public class FactoryMovieTest {
public static void main(String[] args) {
Movie zhanlang = MovieFactory.getFactoryMovie(new ZhanlangMovie());
zhanlang.play();
Music yueliangzhishang = MovieFactory.getFactoryMovie(new YueLiangZhiShang());
yueliangzhishang.play();
}
}
PLAY 之前....
战狼,播放中...
PLAY 之后....
PLAY 之前....
我在遥望,月亮之上...
PLAY 之后....
java 编程基础 Class对象 反射:动态代理 和AOP:java.lang.reflect.Proxy:(Proxy.newProxyInstance(newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h))的更多相关文章
- java 编程基础 Class对象 反射 :数组操作java.lang.reflect.Array类
java.lang.reflect包下还提供了Array类 java.lang.reflect包下还提供了Array类,Array对象可以代表所有的数组.程序可以通过使 Array 来动态地创建数组, ...
- java 编程基础 Class对象 反射 :参数反射
方法参数反射 Java8在java.lang.reflect包下新增了Executable抽象基类,该对象代表可执行的类成员,该类派生了Constructor和Method两个子类.Executabl ...
- java 编程基础 Class对象 反射 :获取类的构造方法,方法,成员变量,内部类,外部类,父类,实现的接口,修饰符等...
类 Class 每个类被加载之后,系统就会为该类生成一个对应的Class对象,通过该Class对象就可以访问到JVM中的这个类. 我们在Java中获取Class对象一般有三种方式: (1), 使用C ...
- java 编程基础 Class对象 反射:代理模式和静态代理
生活中的代理 类(对象)代理模式 代理模式是面向对象编程中比较常见的设计模式. 1. 用户只关心接口功能,而不在乎谁提供了功能.上图中接口是 Subject 2. 接口真正实现者是上图的 RealSu ...
- 【Java核心技术】类型信息(Class对象 反射 动态代理)
1 Class对象 理解RTTI在Java中的工作原理,首先需要知道类型信息在运行时是如何表示的,这是由Class对象来完成的,它包含了与类有关的信息.Class对象就是用来创建所有“常规”对象的,J ...
- 深入理解Java反射+动态代理
答: 反射机制的定义: 是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为j ...
- Java基础加强-(注解,动态代理,类加载器,servlet3.0新特性)
1. Annotation注解 1.1. Annotation概述 Annotation是JDK 5.0以后提供对元数据的支持,可以在编译.加载和运行时被读取,并执行相应的处理.所谓Annota ...
- Java动态代理-->Spring AOP
引述要学习Spring框架的技术内幕,必须事先掌握一些基本的Java知识,正所谓“登高必自卑,涉远必自迩”.以下几项Java知识和Spring框架息息相关,不可不学(我将通过一个系列分别介绍这些Jav ...
- Java动态代理(AOP)
目录 一.代理 1. 什么是代理? 2. 使用代理模式的作用 3. 实现代理的方式 二.静态代理 1. 模拟用户购买u盘 2. 静态代理的缺点 三.动态代理 四. JDK 动态代理 1. Invoca ...
随机推荐
- 关于阿里云图标的使用 iconfont
iconfont 关于阿里云图标库使用的介绍 对于添加到网页中的iconfont可使用以下几种方式: 首先需要进入阿里云图标库官网进行对应的下载iconfont-阿里巴巴矢量图标库 将需要的图标加入到 ...
- Codeforces 1375F - Integer Game(交互)
Codeforces 题面传送门 & 洛谷题面传送门 一个奇怪的做法. 首先我们猜测答案总是 First.考虑什么样的情况能够一步把对方一步干掉.方便起见我们假设 \(a<b<c\ ...
- Yii2 源码分析 入口文件执行流程
Yii2 源码分析 入口文件执行流程 1. 入口文件:web/index.php,第12行.(new yii\web\Application($config)->run()) 入口文件主要做4 ...
- rabbit mq的php使用 amqp 的支持
rabbit mq的php使用 php想要操作rabbit 需要扩展amqp 1,先查看自己的php版本 phpinfo() 接下来下载dll文件 地址http://pecl.php.net/pack ...
- C/C++ Qt StatusBar 底部状态栏应用
Qt窗体中默认会附加一个QstatusBar组件,状态栏组件位于主窗体的最下方,其作用是提供一个工具提示功能,当程序中有提示信息是可以动态的显示在这个区域内,状态栏组件内可以增加任何Qt中的通用组件, ...
- SCRDet——对小物体和旋转物体更具鲁棒性的模型
引言 明确提出了三个航拍图像领域内面对的挑战: 小物体:航拍图像经常包含很多复杂场景下的小物体. 密集:如交通工具和轮船类,在航拍图像中会很密集.这个DOTA数据集的发明者也提到在交通工具和轮船类的检 ...
- 14 - springboot的@Configuration、@Bean、@Import()、@ImportResource()、@Conditional说明
1.@Configuration.@Bean.@Import().@ImportResource().@Conditional 分析源码的时候总会见到标题中的这几个注解,因此:弄一篇博客来说明一下吧, ...
- Flume(一)【概述】
目录 一.Flume定义 二.Flume基础架构 1.Agent 2.Source 3.Sink 4.Channel 5.Event 一.Flume定义 Flume是Cloudera公司提供的一个 ...
- 【STM8】外挂存储器W25Q16
好像有几张图片被强制缩小了?看到这篇博客的人先对你们说声抱歉,我不知道怎么设置 文字就可以很长(文章宽度的全部),图片就只有文章宽度的2/3宽度 开新分页应该就是原始尺寸了,这点还是和大家说抱歉... ...
- java打jar包和运行jar包的两种方式
java打jar包和运行jar包的两种方式更详细的打包方式请参考https://www.cnblogs.com/mq0036/p/8566427.html 一.java类不依赖第三方jar包以简单的一 ...