Java代理示例

1 接口及其實現

public interface Greeting {
    void sayHello(String name);
}
---------------------------------------------
public class GreetingImpl implements Greeting {
    @Override
    public void sayHello(String name) {
        System.out.println( "Hello! " + name );
    }
}

2 靜態代理

public class GreetingProxy implements Greeting {

    private GreetingImpl greeting;

    public GreetingProxy(GreetingImpl greeting){
        this.greeting = greeting;
    }

    @Override
    public void sayHello(String name) {
        before();
        greeting.sayHello(name);
        after();
    }

    private void before(){
        System.out.println("Before");
    }

    private void after(){
        System.out.println("After");
    }
}

3 JDK動態代理

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

// 1. 首先實現一個InvocationHandler,方法調用會被轉發到該類的invoke()方法。
public class JDKDynamicProxy implements InvocationHandler {

    // 目標對象
    private Object target;

    public JDKDynamicProxy(Object target){
        this.target = target;
    }

    // 2. 然後在需要使用Hello的時候,通過JDK動態代理獲取Hello的代理對象。
    @SuppressWarnings("unchecked")
    public <T>T getProxy() {
        // 會返回一個實現了指定接口的代理對象,對該對象的所有方法調用都會轉發給InvocationHandler.invoke()方法
        return (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),  // 指定代理對象的類加載器;
                target.getClass().getInterfaces(),  // 代理對象需要實現的接口,可以同時指定多個接口
                this // 自定義的InvocationHandler,即方法調用的實際處理者,代理對象的方法調用都會轉發到這裏
        );
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before(); // 前置處理
        Object result = method.invoke(target,args);
        after(); // 後置處理
        return result;
    }

    private void before(){
        System.out.println("Before");
    }

    private void after(){
        System.out.println("After");
    }
}

4 CGLIB動態代理

4.1 pom.xml

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>

4.2 Java實現

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

5 測試代碼

public class MainProxy {
    public static void main(String[] args) {
        // staitcProxy();
        jdkDynamicProxy();
        // cglibDynamicProxy();
    }

    private static void staitcProxy(){
        Greeting greeting = new GreetingProxy(new GreetingImpl());
        greeting.sayHello("jtzen9");
    }

    private static void jdkDynamicProxy(){
        JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(new GreetingImpl());
        Greeting greeting = jdkDynamicProxy.getProxy();
        greeting.sayHello("jtzen9");
    }

    private static void cglibDynamicProxy(){
        Greeting greeting = CGLibDynamicProxy.getInstance().getProxy(GreetingImpl.class);
        greeting.sayHello("jtzen9");
    }
}
發佈了93 篇原創文章 · 獲贊 38 · 訪問量 25萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章