代理模式三:CGLib動態代理
阿新 • • 發佈:2018-12-14
1、定義一個類,不實現任何介面,如下:
package aop.demo4;
public class GreetingImpl {
public void sayHello(String name) {
System.out.println("Hello! " + name);
}
}
假如現在有個需求,想要在sayHello方法前後做些事,比如列印日誌。但是不改動GreetingImpl.java本身
2、定義攔截器,實現MethodInterceptor介面,攔截方法
public class CGLibDynamicProxy implements MethodInterceptor
@Override
public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
before();
Object result = proxy.invokeSuper(target, args);
after();
return result;
}
攔截哪個類的方法呢?我們在呼叫的時候傳入真實業務類和攔截器。
3、呼叫Enhancer.create()方法建立代理物件
public <T> T getProxy(Class<T> cls) {
return (T) Enhancer.create(cls, this);
}
2、3兩步的完整程式碼如下:
package aop.demo4; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CGLibDynamicProxy implements MethodInterceptor { private static CGLibDynamicProxy instance = new CGLibDynamicProxy(); private CGLibDynamicProxy() { } public static CGLibDynamicProxy getInstance() { return instance; } @SuppressWarnings("unchecked") public <T> T getProxy(Class<T> cls) { return (T) Enhancer.create(cls, this); } @Override public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable { before(); Object result = proxy.invokeSuper(target, args); after(); return result; } private void before() { System.out.println("Before"); } private void after() { System.out.println("After"); } }
4、客戶端呼叫方式
package aop.demo4;
import aop.Greeting;
/**
* 4. CGLib 動態代理
*/
public class Client {
public static void main(String[] args) {
GreetingImpl greeting = CGLibDynamicProxy.getInstance().getProxy(GreetingImpl.class);
greeting.sayHello("Jack");
}
}
5、執行結果
Before
Hello! Jack
After