二丶JDK动态代理

静态代理和动态代理的区别

静态代理,是指程序运行前就已经存在了代理类的字节码文件,代理类和被代理类的关系在运行前就已经确定。

如上篇所讲,一个静态代理类只代理一个具体类。如果需要对实现了同一接口的不同具体类作代理,静态代理需要为每一个具体类创建相应的代理类。

动态代理类的字节码是在程序运行期间动态生成,所以不存在代理类的字节码文件。代理类和被代理类的关系是在程序运行时确定的。

JDK动态代理

JDK从1.3开始引入动态代理。可通过java.lang.reflect.Proxy类的静态方法Proxy.newProxyInstance动态创建代理类和实例。并且由它动态创建出来的代理类都是Proxy类的子类。

代理类往往会在代理对象业务逻辑前后增加一些功能性的行为,如使用事务或者打印日志。

jdk动态代理模式代码如下:

package myc_demo.proxy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * @program: Demo
 * @description: 人间有味是清欢
 * 动态代理模式
 * @author: liuSha.pufengjun
 * @create: 2018-07-27 09:09
 **/
public class RainProxyHandler implements InvocationHandler {

    private static final Logger logger = LoggerFactory.getLogger(RainProxyHandler.class);

    private Object target;

    public RainProxyHandler(Class clazz) {
        try {
            this.target = clazz.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            logger.info("Create proxy  failed", clazz.getName());
        }
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        pre();
        Object result = method.invoke(target,objects);
        post();
        logger.info("Proxy class name {}", o.getClass().getName());
        return result;
    }

    private void pre() {
        logger.info("RainProxyHandler.pre()");
    }
    private void post() {
        logger.info("RainProxyHandler.post()");
    }
}

测试代理:

package myc_demo.proxy;

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

/**
 * @program: Demo
 * @description: 人间有味是清欢
 * @author: liuSha.pufengjun
 * @create: 2018-07-26 16:45
 **/
public class StaticProxyClient {

    public static void main(String[] args) {
        //静态类里测试类
/*        Rain rain = new ProxyRain();
        rain.raining();*/

        //动态代理测试类
        InvocationHandler handler = new RainProxyHandler(ConcreteRain.class);
       Rain rainProxy = (Rain) Proxy.newProxyInstance(StaticProxyClient.class.getClassLoader(),new Class[]{Rain.class},handler);

        rainProxy.raining();
    }
}

测试结果:

猜你喜欢

转载自blog.csdn.net/qq_22899021/article/details/81236152