Java中使用動態代理可以在運行時動態地創建一個代理對象,用來代替真實的對象進行操作。它有兩種實現方式:基于接口的動態代理和基于類的動態代理。基于接口的動態代理是指通過在運行時動態地創建一個接口的實現類來代替真實對象;基于類的動態代理是指通過在運行時動態地創建一個子類來代替真實對象。
在動態代理中,CGLib是應用得比較廣泛的一種代理實現方式。CGLib是一個強大且靈活的代碼生成庫,它可以在運行時動態地生成一個目標類的子類。在這個子類中,會重寫一些或所有的原類方法,以達到代理的目的。
public class User { private String name; private int age; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } } public class UserProxy implements MethodInterceptor { private Object target; public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; System.out.println("before method " + method.getName()); result = method.invoke(target, args); System.out.println("after method " + method.getName()); return result; } public Object createProxy(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } } public class Client { public static void main(String[] args) { User user = new User(); user.setName("John"); user.setAge(20); UserProxy proxy = new UserProxy(); User userProxy = (User) proxy.createProxy(user); System.out.println(userProxy.getName()); System.out.println(userProxy.getAge()); } }
上面是一個簡單的CGLib動態代理示例,可以理解為對原本的User類進行了一層代理,我們可以在代理中對其方法進行增強。CGLib的優勢在于它不用像JDK動態代理那樣要求被代理類必須實現接口,更加靈活。