前言
静态代理和动态代理
- 或者你是老板(大忙人),只想请明星过来做事,合同写好要求,但具体的怎么实现老板不想插手太细,老板只需要和经纪人题好要求,有经纪人去指挥明星完成,老板只看效果怎么样,不管过程。
类与类之间关系的回顾
强烈推荐这篇博客类与类之间的几种关系
一、静态代理
利用继承和向上转型的方式或者是实现接口的方式规范大家的数据类型确保返回类型一致。
说白了代理对象根据委托人去调用被代理对象具体实现,委托人
举个栗子:数据类型为T的 f 方法,当使用 f 方法的返回必需要调用多个其他类的方法产生的对象,这多个其他类产生的对象不一样,但是return只有一个,为了灵活生产并使用数据类型为T的 f 方法。
好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 公共也就就交给代理角色!实现业务的分工!
- 公共业务发生扩展的时候,方便集中管理
缺点
- 一个真实角色就会产生一个代理角色;代码量会翻倍~开发效率会变低
二、动态代理
场景与使用方式
场景:经济人和明星
使用方式:泛型、反射
好处:
- 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
- 公共也就就交给代理角色!实现业务的分工!
- 公共业务发生扩展的时候,方便集中管理
- 一个动态代理类 代理的是一个接口,一般就是对应的一类业务
- 一个动态代理类 可以代理多个类 只要实现了同一个接口即可
代码如下:
package dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 写这个类的目的是为了
* 让这个类帮我们创建一个代理对象
*/
public class ProxyFactory {//这个代理工厂是我自己写的 有一个方法
//描述一个方法 通过Proxy这个类获取一个代理对象(代工商店)
// 1.方法是一件事情 做事情之前是否需要条件---参数 代理谁? AppleStore
// 2.方法是一件事情 做事情之后是否需要结果---返回值 代理对象--利用泛型
public static <T>T getStore(Class clazz){//clazz--->AppleStore
return (T)Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是代工厂 做事啦");
return new iPhone("iPhone7", "black");
}
});
// //分析创建proxy代理对象需要的条件
// //0.类加载器---目的是把需要代理的AppleStore这个类加载进来
// ClassLoader classLoader = clazz.getClassLoader();
// //1.代理谁 AppleStore(传递的参数clazz) 下面第二个问号需要数组
// Class[] classes = new Class[]{clazz};
// //2.代理他之后 具体该做什么事情---原来真正店做的事情 卖手机
// InvocationHandler handler = new InvocationHandler(){
// public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// //内部类中方法的三个参数含义
// //1.proxy代理对象 2.method代理的那个方法 3.args代理方法传递的参数
// if(method.getName().equals("saleiPhone")) {
// //这个方法就是那个代工对象具体做的事情
// // 他做的事情就是代替原来真正AppleStore做的事情
// System.out.println("我是代工厂 做事啦");
// iPhone iPhone = new iPhone("iPhone7", "black");
// return iPhone;
// }else{
// System.out.println("别的方法");
// return null;
// }
// }
// };
// //1.通过Proxy类帮我们创建一个代理对象
// T proxy = (T)Proxy.newProxyInstance(classLoader,classes,handler);
// //2.将这个proxy代理对象返回
// return proxy;
}
}
jdk动态代理
JDK中的动态代理是通过反射类Proxy以及InvocationHandler回调接口实现的
缺点:JDK中所有要进行动态代理的类必须要实现一个接口
cglib动态代理
使用cglib是实现动态代理,因为cglib底层是用ASM框架,使用字节码技术生成代理类,动态生成被代理类的子类
缺点:cglib不能对声明final的方法进行代理