1. 程式人生 > 實用技巧 >java靜態代理、動態代理、cglib代理

java靜態代理、動態代理、cglib代理

首先定義一個介面:

public interface AdminControl {
    void find();
    void update();
    void add();
}

實現類:

public class AdminControlImpl implements AdminControl{
    public void find() {
        System.out.println("查詢所有管理員資訊");
    }

    public void update() {
        System.out.println("修改管理員資訊");
    }

    
public void add() { System.out.println("增加管理員資訊"); } }

靜態代理

public class AdminControlProxy implements AdminControl{
    private AdminControl adminControl;
    public AdminControlProxy(AdminControl adminControl){
        this.adminControl = adminControl;
    }
    public void find() {
        System.
out.println("進入方法find"); adminControl.find(); System.out.println("退出方法find"); } public void update() { System.out.println("進入方法update"); adminControl.update(); System.out.println("退出方法update"); } }

代理模式可以在不修改被代理物件的基礎上,通過擴充套件代理類,進行一些功能的附加與增強.

靜態代理缺點:

1.假設系統中需要代理的service過多,那麼就會建立很多代理物件

2.假設代理的service方法改變,那麼相應的代理物件也會改變

動態代理

  • proxy 代理物件
  • method 代理物件呼叫的方法
  • args 呼叫的方法中的引數
public class AdminControlInvocation implements InvocationHandler {
    private Object object;
    public AdminControlInvocation(Object object){
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("進入方法"+method.getName());
        Object object = method.invoke(object,args);
        System.out.println("退出方法"+method.getName());
        return object;
    }
}

假設代理的物件沒有介面,那麼就不能使用動態代理

cglib代理

首先引入依賴

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

程式碼

public class AdminControlCglibProxy implements MethodInterceptor {
    private Object object;
    public AdminControlCglibProxy(Object object){
        this.object = object;
    }
    public Object getProxyInstance(){
        Enhancer enhancer = new Enhancer();
        // 設定代理類的父類
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("進入方法"+method.getName());
        Object object = method.invoke(object,objects);
        System.out.println("退出方法"+method.getName());
        return object;
    }
}

對於一個沒有介面的類,使用cglib代理,前提,該類必須可以被繼承,方法不能為final、static。

cglib是採用動態建立子類的方法來代理