代理模式

https://www.cnblogs.com/jie-y/p/10732347.html

https://www.cnblogs.com/zuidongfeng/p/8735241.html

https://www.cnblogs.com/shoshana-kong/p/9041485.html

 

jdk动态代理

1、 新建一个接口

package dynamicProxy;
/**
* @author lixiang:
* @version 创建时间:2020年1月18日 下午7:33:44
* 类说明
*/
public interface IStar {
    void sing();
}

 

2、 为接口创建一个实现类

package dynamicProxy;
/**
* @author lixiang:
* @version 创建时间:2020年1月18日 下午7:49:04
* 类说明
*/
public class Star implements IStar {

    @Override
    public void sing() {
        System.out.println("歌星在唱歌");

    }

}

 

3、 创建代理类实现java.lang.reflect.InvocationHandler接口

package dynamicProxy;

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

/**
* @author lixiang:
* @version 创建时间:2020年1月18日 下午9:02:39
* 类说明 :动态代理对象实现invoke方法
*/
public class MyInvocationHandler implements InvocationHandler {
    //目标对象
    private Object target;
    
    public void setTarget(Object target) {
        this.target = target;
    }
    //该方法在使用代理Proxy.newProxyInstance时会调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        ZengQiangLei.singBefore();
        //通过method.invoke(obj,args)反射获取要增强的方法
        method.invoke(target, args);
        ZengQiangLei.singAfter();
        return null;
    }

}

 

4、 设置一个生成代理的工厂

package dynamicProxy;

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

/**
* @author lixiang:
* @version 创建时间:2020年1月18日 下午8:07:46
* 类说明
*/
public class MyProxyFactory {
    
    public static  Object getProxy(Object target) {
        MyInvocationHandler handler = new MyInvocationHandler();
        //将要增强的对象传递给handler
        handler.setTarget(target);
        /*动态代理核心方法
         * public static Object newProxyInstance(ClassLoader loader,
        Class<?>[] interfaces,
        InvocationHandler h)
        loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
        interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,
                           如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
        h:    一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,
             会关联到哪一个InvocationHandler对象上
        */
         Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                        target.getClass().getInterfaces(), handler);
        return proxy;
        
    }

}

5、设置一个增强方法的类

package dynamicProxy;
/**
* @author lixiang:
* @version 创建时间:2020年1月18日 下午7:49:30
* 类说明  
*/
public class ZengQiangLei {
    
    public static void singBefore() {
        System.out.println("歌星唱歌前准备,先吃个饭。。。。。。");
    }
    
    public static void singAfter() {
        System.out.println("歌星唱歌结束了。。。。。。。。");
    }
}

6、测试

package dynamicProxy;

import org.junit.Test;

/**
* @author lixiang:
* @version 创建时间:2020年1月18日 下午10:12:40
* 类说明
* 不用像静态代理一样代理类也实现接口,避免了接口类增加
* 方法,代理对象和代理都要维护的麻烦
*/
public class DynamicTest {
    @Test
    public void test01() {
        IStar star = new Star();
        //通过传递目标对象,获取代理类
        IStar proxy = (IStar) MyProxyFactory.getProxy(star);
        //这样当我们想改变要增强的方法时,直接改变增强类就ok
        proxy.sing();
    }

}

结果:当需要改变增强方法时,只需要更改增强类

歌星唱歌前准备,先吃个饭。。。。。。
歌星在唱歌
歌星唱歌结束了。。。。。。。。
posted @ 2020-01-18 23:20  我差两天十八岁  阅读(91)  评论(0编辑  收藏  举报