优点:实现业务分工、方便公共业务的扩展和集中管理、不改变原有代码,通过增加代理增加功能
步骤:1.业务接口 2.真实角色 3.代理角色 4.客户端访问代理
静态代理
缺点:每个真实角色都会产生代理,开发效率变低
interface eat { //抽象接口
void eating();
}
class food implements eat { //真实类,单一功能
@Override
public void eating() {
System.out.println("直接手抓着吃");
}
}
class kuaZi implements eat {
//代理类,重写抽象方法,在实现真实类的基础上,添加新功能
private food food;
public kuaZi(Test.food food) {
this.food = food;
}
@Override
public void eating() {
food.eating();
watch();
kuaizichi();
}
public void kuaizichi() {
System.out.println("用筷子吃");
}
public void watch() {
System.out.println("洗手");
}
}
动态代理
JDK动态代理主要涉及两个类:java.lang.reflect.Proxy(代理类) 和 java.lang.reflect.InvocationHandler(调用处理程序接口)
通过反射动态生成代理类,分为两大类:1、基于接口的动态代理 2、基于类的动态代理
第一步:写一个抽象接口(功能抽象)
public interface ByCar {
public void by();
}
第二步:被代理类去实现这个接口
public class Me implements ByCar{
@Override
public void by() {
System.out.println("买一辆新车");
}
}
第三步:代理类设置接口为属性并写构造方法、重写InvocationHandler中的invoke方法(因为当我们通过代理类实现接口方法时,调用的是invoke里的方法,这里需要用methon.invoke添加原来的方法)
public class Other implements InvocationHandler {
private ByCar byCar;
public Other(ByCar byCar) {
this.byCar = byCar;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//添加新功能
System.out.println("新功能一号");
System.out.println("新功能二号");
System.out.println("新功能三号");
method.invoke(byCar,args);//这一句是添加原来的方法
return null;
}
}
第四步:main测试--实例化被代理类、实例化代理类赋给invocationHangler、实例化代理接口、接口对象调用方法(实际上是invoke方法)
public static void main(String[] args) {
ByCar byCar=new Me(); //实例化被代理类
InvocationHandler invocationHandler=new Other(byCar); //实例化代理类赋给invocationHandler
ByCar proxy= (ByCar) Proxy.newProxyInstance //代理接口实例:Proxy.newProxyInstance,下面是三个参数
(byCar.getClass().getClassLoader(), //1.被代理类的类加载器
byCar.getClass().getInterfaces(), //2.被代理类所实现的接口
invocationHandler); //3.实现invacationHandler接口的类对象
proxy.by(); //代理类调用目标方法(具体执行的是invoke方法)
}
}