Java 靜態代理和動態代理


1、靜態代理,實現代碼如下,實際上是對裝飾器模式的一種應用

interface UserManager {
    public void addUser();
}

class UserManagerImpl implements UserManager {
    public void addUser() {
        System.out.println("raw addUser");
    }
}

class UserManagerImplProxy implements UserManager {
    private UserManager userManager;
    
    public UserManagerImplProxy(UserManager userManager) {
        this.userManager = userManager;
    }
    
    public void addUser() {
        System.out.println("in proxy");
        userManager.addUser();
    }
}
public class ProxyTest {
    public static void main(String args[]) {
        UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
        userManager.addUser();
    }
}

2、動態AOP,借助 java.lang.reflect.InvocationHandler接口 和 java.lang.reflect.Proxy 類實現 

java.lang.reflect.InvocationHandler接口的定義如下:

public interface InvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

Object proxy:被代理的對象

Method method:要調用的方法

Object[] args:方法調用時所需要參數

invoke 方法用於切面處理,調用相應的方法

java.lang.reflect.Proxy類的定義如下:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

 

CLassLoader loader: 類的加載器

Class<?> interfaces: 得到全部的接口

InvocationHandler h: 實現 InvocationHandler 接口的子類的實例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface UserManager {
    public void addUser();
}

class UserManagerImpl implements UserManager {
    public void addUser() {
        System.out.println("raw addUser");
    }
}

class UserManagerImplProxy implements InvocationHandler {
    
    private Object targetObject;
    
    public void log() {
        System.out.println("message info");
    }
    
    public Object createProxyInstance(Object targetObject) {
        this.targetObject = targetObject;
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        log();
        Object ret = method.invoke(targetObject, args);
        return ret;
    }
}
public class ProxyTest {
    public static void main(String args[]) {
        UserManagerImplProxy proxy = new UserManagerImplProxy();
        UserManager manager = (UserManager) proxy.createProxyInstance(new UserManagerImpl());
        manager.addUser();
    }
}

3、動態代碼字節生成

CGLib是動態代碼字節生成的實現,它封裝字節碼生成工具Asm,原理是在運行期間目標字節碼加載后,生成目標類的子類,將切面邏輯加入到子類中,所以使用Cglib實現AOP不需要基於接口。cglib 的核心是實現 MethodInterceptor 接口,使用 intercept() 方法進行面向切面的處理,調用相應的通知。其中 cglib 中有一個 Enhancer 類,可以使用他快速的創建一個代理類。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

interface UserManager {
    public void addUser();
}

class UserManagerImpl implements UserManager {
    public void addUser() {
        System.out.println("raw addUser");
    }
}

class CGLIBProxyFactory implements MethodInterceptor{
    // 要放回的代理對象
    private Object obj;

    public Object createProxy(Object obj) {
        // 把傳進來的代理對象賦值給obj
        this.obj = obj;
        Enhancer enhancer = new Enhancer();
        // 需要為其實例指定一個父類,也就是我們 的目標對象,那么我們新創建出來的對象就是目標對象的子類,有目標對象的一樣
        enhancer.setSuperclass(this.obj.getClass());
        // 除此之外,還要指定一個回調函數,這個函數就和Proxy的 invoke()類似
        enhancer.setCallback(this);
        return enhancer.create();

    }
    
    public void log() {
        System.out.println("message info");
    }
    
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object proxyObject = null;
        UserManagerImpl um = (UserManagerImpl) obj;
        log();
        proxyObject = methodProxy.invoke(um, args);
        return proxyObject;
    }

}

public class ProxyTest {
    public static void main(String args[]) {
        CGLIBProxyFactory gb = new CGLIBProxyFactory();
        UserManager manager = (UserManager)gb.createProxy(new UserManagerImpl());
        manager.addUser();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM