1. 程式人生 > >Java 8中的靜態代理和動態代理的簡單心得

Java 8中的靜態代理和動態代理的簡單心得

歡迎來到我的第一個部落格

個人學習的一點心得,第一次寫寫的不好見諒

簡單做的圖片看看就好

看看程式碼吧

程式碼1.

public interface CarSales {
    void sell();
}

程式碼2.

public class QQCar implements CarSales {
    @Override
    public void sell() {
        System.out.println("出售qq汽車排量1.0L");
    }
}

程式碼3.

public class Benz implements CarSales
{ @Override public void sell() { System.out.println("出售賓士S級汽車和邁巴赫"); } }

程式碼4.

public interface Sales {
    void sell();
}

程式碼5.

public class Owner implements Sales {
    @Override
    public void sell() {
        System.out.println("我是房東,我正在出售我的公寓");
    }
}

程式碼6.

public class Owner2 implements Sales {
    @Override
    public void sell() {
        System.out.println("我想出售別墅");
    }
}

程式碼7.

public class SalesInvocationHandler implements InvocationHandler {

    private Object delegate;

    public Object bind(Object delegate){
        this.delegate=delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(), this); } // public SalesInvocationHandler(Object delegate) { // this.delegate = delegate; // } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(proxy.getClass().getInterfaces()[0]); System.out.println("中介1幫你檢查資訊"); Object result = method.invoke(delegate, args); System.out.println("中介1向你收取中介費"); return result; } }

程式碼8.

public class SalesInvocationHandler2 implements InvocationHandler {

    private Object delegate;

    public Object bind(Object delegate){
        this.delegate=delegate;
        return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(), this);
    }



    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getInterfaces()[0]);
        System.out.println("中介2幫你檢查房產資訊");
        Object result = method.invoke(delegate, args);
        System.out.println("中介2幫你做衛生");
        return result;

    }
}

程式碼9.

public class SalesInvocationHandler3 implements InvocationHandler {
    private Object delegate;

    public Object bind(Object delegate){
        this.delegate=delegate;
        return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),delegate.getClass().getInterfaces(), this);
    }



    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getInterfaces()[0]);
        System.out.println("中介3幫你買保險");
        Object result = method.invoke(delegate, args);
        System.out.println("中介3請你吃飯");
        return result;

    }
}

程式碼10.

public class Customer {
    public static void main(String[] args) {
        Sales delegate=new Owner();
//        InvocationHandler handler=new SalesInvocationHandler(delegate);
        Sales proxy= (Sales)new SalesInvocationHandler().bind(delegate);
        proxy.sell();

        Sales delegate2=new Owner2();
        Sales proxy2= (Sales)new SalesInvocationHandler().bind(delegate2);
        proxy2.sell();

        Sales proxy3= (Sales)new SalesInvocationHandler2().bind(delegate);
        proxy3.sell();

        Sales proxy4= (Sales)new SalesInvocationHandler2().bind(delegate2);
        proxy4.sell();

        CarSales car1=new Benz();
        CarSales proxy5= (CarSales) new SalesInvocationHandler().bind(car1);
        proxy5.sell();

        CarSales proxy6= (CarSales) new SalesInvocationHandler3().bind(car1);
        proxy6.sell();

        CarSales car2=new QQCar();
        CarSales proxy7= (CarSales) new SalesInvocationHandler3().bind(car2);
        proxy7.sell();


    }
}

執行結果如下:

中介1幫你檢查資訊
我是房東,我正在出售我的公寓
中介1向你收取中介費
interface dongtaigaijin.Sales
中介1幫你檢查資訊
我想出售別墅
中介1向你收取中介費
interface dongtaigaijin.Sales
中介2幫你檢查房產資訊
我是房東,我正在出售我的公寓
中介2幫你做衛生
interface dongtaigaijin.Sales
中介2幫你檢查房產資訊
我想出售別墅
中介2幫你做衛生
interface dongtaigaijin.CarSales
中介1幫你檢查資訊
出售賓士S級汽車和邁巴赫
中介1向你收取中介費
interface dongtaigaijin.CarSales
中介3幫你買保險
出售賓士S級汽車和邁巴赫
中介3請你吃飯
interface dongtaigaijin.CarSales
中介3幫你買保險
出售qq汽車排量1.0L
中介3請你吃飯
$-------------------------------------------------------------------------------------------------------------------------------
CGLIB動態代理

程式碼1.

package cglib_test;

/**
 * @description: 普通類,不用實現介面的
 * @create: 2018-10-18
 **/
public class My85 {
    public void sell(){
        System.out.println("賣麵包的");
    }
}

程式碼2.

package cglib_test;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.logging.Logger;

/**
 * @description: ${description}
 * @create: 2018-10-18
 **/
public class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Logger log1 = Logger.getLogger("log1");
        log1.info("這是臺灣的麵包店");
        System.out.println("這是臺灣的麵包店");
        return methodProxy.invokeSuper(o,objects);
    }
}

程式碼3.

package cglib_test;

import net.sf.cglib.proxy.Enhancer;
/**
 * @description: ${description}
 * @create: 2018-10-18
 **/
public class Test {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(My85.class);
        enhancer.setCallback(new MyMethodInterceptor());

        My85 my85 = (My85)enhancer.create();
        my85.sell();
    }
}

程式碼4 (2的改進版本)`.

package cglib_test;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @description: ${description}
 * @create: 2018-10-18
 **/
public class MyMethodInterceptor2 implements MethodInterceptor {
    private Object target;

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

    public Object createProxy(){
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(this);
        enhancer.setSuperclass(this.target.getClass());
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("aaaaaaaaaaaaa");//切面a
        method.invoke(this.target,objects);
        System.out.println("bbbbbbbbbbbbb");//切面b
        return null;
    }
}

程式碼5(3的後續).

package cglib_test;

import net.sf.cglib.proxy.Enhancer;

/**
 * @description: ${description}
 * @create: 2018-10-18
 **/
public class Test {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(My85.class);
        enhancer.setCallback(new MyMethodInterceptor());
        My85 my85 = (My85) enhancer.create();
        my85.sell();
        System.out.println("樓上是JDK動態代理.樓下是CGLIB動態代理啊啊啊啊啊");
        My85 my86 = new My85();
        MyMethodInterceptor2 myMethodInterceptor2 = new MyMethodInterceptor2(my86);
        My85 proxy2 = (My85) myMethodInterceptor2.createProxy();
        proxy2.sell();
    }
}

控制檯顯示結果:

在這裡插入圖片描述

#-----------------------------------------------------------------------------------------------------------------------------------#

實際中的應用案例:

1/spring中的bean後處理器
2/Mybatis-Spring中使用動態代理
3/Spring動態代理 日誌和事務,實現非業務邏輯和業務邏輯分開

動態代理分為兩種:

1-jdk的動態代理
1.1 代理物件和目標物件實現了共同的介面
1.2攔截器必須實現InvocationHanlder介面
2-cglib的動態代理
2.1代理物件是目標物件的子類
2.2攔截器必須實現MethodInterceptor介面
2.3hibernate中session.load採用的是cglib實現的

參考文:https://blog.csdn.net/qq_27093465/article/details/53340513

部分材料取材自github
慢慢更新完善這個部落格