java代理模式
什么是代理模式:对其他对象提供一种代理以控制对这个对象的访问
为什么使用代理模式:代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。也就是说,代理就像一个中介,在不改变原对象的基础上能扩展功能。
代理模式佑哪几种:静态代理、动态代理、Cglib代理
1.静态代理:静态代理在使用时,需要定义接口或者父类,被代理对象(目标对象)与代理对象(委托对象),一起实现相同的接口或者是继承相同父类。
定义接口
public interface Person { public void giveMoney(); public void giveHouse(); public void giveJob(); }
定义目标对象
public class Student implements Person { @Override public void giveMoney() { // TODO Auto-generated method stub System.out.println("50元"); } @Override public void giveHouse() { System.out.println("五环"); } @Override public void giveJob() { System.out.println("阿里巴巴工程师"); } }
定义委托对象
public class StudentProxy implements Person{ //接收保存目标对象 private Student student; public StudentProxy(Student student) { this.student=student; } @Override public void giveMoney() { //扩展功能 System.out.print("学习有进步"); //调用目标对象方法 student.giveMoney(); } @Override public void giveHouse() { System.out.println("卖房了"); student.giveHouse(); } @Override public void giveJob() { // TODO Auto-generated method stub } }
测试类
public class Test { public static void main(String[] args) { Student student=new Student(); StudentProxy studentProxy=new StudentProxy(student); studentProxy.giveMoney(); studentProxy.giveHouse(); } }
静态代理缺点:由于目标对象和委托对象都要实现接口中所有的类,比较麻烦。而且当接口新增或减少功能时,委托和目标对象都要修改
2.动态代理
注意:动态代理的委托对象是一个接口,不能是实例
定义接口:
public interface Animal { public void eat(); public void drink(); }
定义目标对象:
public class Pig implements Animal { public void eat() { System.out.print("pig eat anything can be ate"); } public void drink() { System.out.print("pig drink fresh water"); } }
定义获取委托对象的工厂
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyFactory implements InvocationHandler { //定义委托对象 Object warpedPerson; //获取并保存目标对象 private Object target; public ProxyFactory(Object target) { this.target=target; } //创建并返回委托对象 public Object getProxyInstance() { warpedPerson= Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); return warpedPerson; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //对目标对象的功能进行扩展 System.out.print("代理做的 "); //如果目标对象的方法名为eat,则执行这个操作而不执行目标对象自己的操作 if(method.getName().equals("eat")) System.out.print("it depends on what you give them"); //目标对象的其他方法都执行他自己定义的方法,委托对象不管 return method.invoke(this.target, args); } }
定义测试类:
public class Test { public static void main(String[] args) { Pig pig = new Pig(); Animal pigProxy = (Animal) new ProxyFactory(pig).getProxyInstance(); pigProxy.drink(); pigProxy.eat(); } }