JDK動態代理相關(一)
阿新 • • 發佈:2018-12-11
一、JDK的動態代理
代理模式最主要的就是有一個公共介面(Person),一個具體的類(Student),一個代理類(StudentsProxy),代理類持有具體類的例項,代為執行具體類例項方法。
簡單實現如下:
//公共介面類 public interface Person { public String sayHello(); public String eating(String name); } //實現類 public class Student implements Person { private Long id; private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Student() { } @Override public String sayHello( ) { System.out.println(name+"-- sayHello() --"); return name + " hello, AOP"; } @Override public String eating(String name) { // TODO Auto-generated method stub System.out.println(name+" is eating someThing........."); return null; } public void eat(String food){ System.out.println("我正在吃:" + food); } } //實現InvocationHandler 介面的類 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class StuInvocationHandler<T> implements InvocationHandler { private T stu; public StuInvocationHandler(T stu) { this.stu = stu; } public void doSomeThingBefore(){ System.out.println("before..............."); } public void doSomeThingAfter(){ System.out.println("after................"); } /** * proxy:代表動態代理物件 * method:代表正在執行的方法 * args:代表呼叫目標方法時傳入的實參 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { doSomeThingBefore(); Object ob = method.invoke(this.stu,args); doSomeThingAfter(); return ob; } } //測試呼叫 public class ProxyTest { public static void main(String[] args) { Student stu = new Student(); stu.setName("zhangsan"); //建立一個與代理物件相關聯的InvocationHandler InvocationHandler stuHandler = new StuInvocationHandler<Person>(stu); //建立一個代理物件stuProxy來代理zhangsan,代理物件的每個執行方法都會替換執行Invocation中的invoke方法 Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler); //Student stuProxy = (Student) Proxy.newProxyInstance(Student.class.getClassLoader(), new Class<?>[]{Student.class}, stuHandler); //代理物件必須是介面型別 否者編譯失敗: Student is not an interface //代理執行上交班費的方法 stuProxy.sayHello(); stuProxy.eating("zhangsan"); } }