1. 程式人生 > >java靜態代理與動態代理用法

java靜態代理與動態代理用法

代理模式是指通過代理物件來訪問目標物件,這樣便於在目標物件的功能基礎之上新增額外的功能擴充套件,並且不需要改變原目標物件的程式碼。

1、靜態代理

靜態代理比較簡單,代理類與目標類實現同一個介面,把目標類的物件新增進代理類中,然後在代理類的方法中呼叫目標類的方法,程式碼如下:

介面

public interface People {
void eat();

}

目標類

public class Student implements People{
@Override
public void eat() {
System.out.println("在學校食堂吃飯");
}

}

代理類

public class StudentProxy implements People{
private Student student;
public StudentProxy(Student student)
{
this.student = student;
}
@Override
public void eat() {
System.out.println("前攔截");
student.eat();
System.out.println("後攔截");
}

}

測試類:

public class Test {
public static void main(String[] args) {
Student student = new Student();
StudentProxy studentProxy = new StudentProxy(student);
studentProxy.eat();
}

}

執行結果:

前攔截
在學校食堂吃飯

後攔截

優點:在不改變原有目標類的情況下,擴充套件目標類的功能

缺點:因為代理類也需要實現介面,所以當介面中方法一多,代理類也需要重新維護,但是往往我們可能只需要代理目標類中某一個方法,這種情況下,使用靜態代理就比較麻煩,可以使用動態代理

2、動態代理

介面

public interface People {
void eat();

}

目標類

public class Student implements People{
@Override
public void eat() {
System.out.println("在學校食堂吃飯");
}

}

動態代理類

public class DynamicProxy implements InvocationHandler{
private People people;
public DynamicProxy(People people) {
this.people = people;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("動態代理攔截前");
method.invoke(people, args);
System.out.println("動態代理攔截後");
return null;
}

}

測試類

public class Test {
public static void main(String[] args) {
People student = new Student();
DynamicProxy dynamicProxy = new DynamicProxy(student);
People proxy = (People) Proxy.newProxyInstance(student.getClass().getClassLoader(), new Class[]{People.class}, dynamicProxy);
proxy.eat();
}
}

執行結果:

動態代理攔截前
在學校食堂吃飯

動態代理攔截後

優點:當介面增加方法時,代理類並不需要重新維護。