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(); } }
