在java开发中常用到代理的场景,通俗解释 代理是指 帮助目标对象 去完成目标对象所要完成的事情。比如说 点外卖 目标对象是 顾客 顾客需要点一份米饭从餐馆 外卖小哥 就充当代理对象 帮助顾客取餐 送餐
静态代理
可通过继承或者实现接口完成代理
目标类
public class Customer {
public String clickOrder(String food){
return "顾客下单"+food+"成功";
}
}
代理类
public class PorxyObj extends Customer{
@Override
public String clickOrder(String food) {
super.clickOrder(food);
System.out.println("外卖接到订单");
System.out.println("外卖接取到餐");
System.out.println("外卖接开始配送");
return "收到"+food;
}
}
执行代理类
public static void main(String[] args) {
Customer customer = new PorxyObj();
String food = customer.clickOrder("麻辣烫");
System.out.println(food);
}
实现接口同理
静态代理很好的将对象关系做了解耦,但相对于框架本身来说 不利于扩展 ,如果目标对象做了改动,均会影响到代理对象,因此 动态代理应运而生。
动态代理
1、基于JDK API实现的动态代理(要求目标对象实现接口)
定义interface
public interface OrderInterface {
String clickOrder(String food);
}
定义实现类
public class Customer implements OrderInterface{
@Override
public String clickOrder(String food) {
System.out.println("下单"+food+"成功");
return food;
}
}
利用JDK Proxy.newProxyInstance 创建动态代理类 返回 对象为接口类型对象 必须用接口类型接收
public static void main(String[] args) {
Customer customer = new Customer();
OrderInterface orderInterface = (OrderInterface) Proxy.newProxyInstance(customer.getClass().getClassLoader(), customer.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object res = method.invoke(customer,args);
System.out.println("外卖接到订单");
System.out.println("外卖接取到餐");
System.out.println("外卖接开始配送");
return "收到"+res;
}
});
System.out.println(orderInterface.clickOrder("大盘鸡"));
}
2、基于cglib 实现动态代理 (无需实现接口 cglib是基于父类实现的动态代理)
目标类
public class Customer {
public String clickOrder(String food){
return "顾客下单"+food+"成功";
}
}
利用 Enhancer.create 生成动态代理类 由于cglib是基于父类的 所以生成的代理类 类型为 目标对象的子类
public static void main(String[] args) {
Customer customer = new Customer();
Customer customerChild = (Customer) Enhancer.create(customer.getClass(), new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object res = method.invoke(customer,objects);
System.out.println("外卖接到订单");
System.out.println("外卖接取到餐");
System.out.println("外卖接开始配送");
return "收到"+res;
}
});
System.out.println(customerChild.clickOrder("蚂蚁上树"));
}
cglib 对开发者来说 最为简单 但需引入cglib 相关jar包
JDK Proxy 是jdk官方的 无需引入第三方jar包