1. 程式人生 > >代理模式三:CGLib動態代理

代理模式三:CGLib動態代理

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