Files
javaSE-0113/javaSE-day13/src/com/inmind/proxy01/Demo03.java

99 lines
5.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.inmind.proxy01;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
/*
静态代理:直接定义一个固定的类,增强某个类的功能(JingJiRen)
动态代理:不用定义一个固定的类,动态地增强某个类的功能
需求:蔡徐坤的类不能改变,也不能定义经纪人类,但是还想对蔡徐坤的唱跳功能,增强金额判断
此时只能使用动态代理.
--------------------------------------------------------------------------
总结:
装饰设计模式(静态代理):
装饰者 被装饰者 作用:装饰者增强了被装饰者的功能
花瓶 花 花瓶增强了花的好看的程度
经纪人JingJiRen 歌手CaiXuKun 经纪人增强了蔡徐坤的经济价值
装饰设计模式的前提: 装饰者需要与被装饰者的功能要一致,继承同一个父类或者实现同一个接口
BufferedReader FileReader 字符缓冲输入流增加了一个8192数组增强了字符输入流的读取的效率
--------------------------------------------------------------------------------------------------------------
动态代理
代理者 被代理者 作用:代理者能拦截被代理者的指定的功能,进行业务操作
singerProxy 蔡徐坤 拦截了caiXuKun的singdance方法增加了金额的判断功能
动态代理的前提条件:代理者与被代理者必须拥有相同的功能,实现同一个接口
静态代理与动态代理的区别:
1.装饰设计模式:注重功能的增强,拥有更多的功能代码,它必须实现所有的抽象方法
2.动态代理:注重功能方法的拦截,它只需要针对想拦截的方法即可
*/
public class Demo03 {
public static void main(String[] args) {
//创建出被代理的类-蔡徐坤
CaiXuKun caiXuKun = new CaiXuKun();
//动态代理参数一:类加载器
ClassLoader classLoader = caiXuKun.getClass().getClassLoader();
//动态代理参数二:代理对象要与被代理对象拥有相同的功能,(实现同一套接口)
Class<?>[] interfaces = caiXuKun.getClass().getInterfaces();
//动态代理参数三:处理器对象,用来处理代理对象的业务逻辑
InvocationHandler handler = new InvocationHandler() {
/*
注意动态代理对象singerProxy调用任意方法功能都会引起处理器的invoke方法来执行
invoke方法的三个参数:
参数一proxy:动态代理对象singerProxy(不要在invoke方法中使用,它引起递归,导致栈内存溢出错误)
参数二method:反射中Method类,就是当前动态代理调用的方法sing,dance...
参数三args:当前动态代理调用的方法传入的实参
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
业务需求:将经纪人的功能,设置在此
1.如果是sing,那么要100万才让蔡徐坤唱
2.如果是dance,那么要120万才让蔡徐坤跳
*/
if ("sing".equals(method.getName())) {
//获取sing方法的实参
int money = (int) args[0];
if (money > 100) {
// caiXuKun.sing(money);
return method.invoke(caiXuKun,args);
} else {
System.out.println("钱不够,一边玩去");
return null;
}
}
if ("dance".equals(method.getName())) {
//获取dance方法的实参
int money = (int) args[0];
if (money > 120) {
// caiXuKun.dance(money);
return method.invoke(caiXuKun,args);
}else {
System.out.println("钱不够,一边玩去");
return null;
}
}
//注意我们此时针对singdance进行拦截但是其他的方法功能还要保留不要拦截那就是执行原本的功能
return method.invoke(caiXuKun,args);//执行蔡徐坤原本的功能
}
};
//动态地创建出一个代理对象(类似一个经纪人)
Singer singerProxy = (Singer) Proxy.newProxyInstance(classLoader, interfaces, handler);//多态
// System.out.println(singerProxy);//toString
// singerProxy.sing(50);
singerProxy.dance(150);
// singerProxy.eat();
// singerProxy.toString();
}
}