代理模式

1.静态代理

接口

package ProxyDemo.staticProxy;

public interface Person {

    void findJob();

}

委托类

package ProxyDemo.staticProxy;

public class Tom implements Person{
    @Override
    public void findJob() {
        System.out.println("我要找工作!静态代理!");
    }
}

静态代理类

 

package ProxyDemo.staticProxy;

/**
 * 静态代理 自己创建代理类,调用之前代理类已经存在
 *
 * 缺点:
 * 代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。
 * 这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。
 * 增加了代码维护的复杂度。不符合开闭原则
 *
 * 代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理
 *
 */
public class StaticProxy implements Person {


    private Person person;

    public StaticProxy(Person person) {
        this.person = person;
    }

    @Override
    public void findJob() {

        before();

        person.findJob();

        after();
    }


    public void before(){
        System.out.println("调用之前增强!静态代理");
    }

    public void after(){
        System.out.println("调用之后增强!静态代理");
    }
}

 

2.JDK动态代理

接口

public interface Person {

    void findJob();

}

委托类

package ProxyDemo.JDKDynamic;

public class Jim implements Person {

    @Override
    public void findJob() {
        System.out.println("我要找工作!");
    }
}

 JDK动态代理类

package ProxyDemo.JDKDynamic;

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

/**
 * 动态代理
 * 最大的特点是 符合开闭原则 当被代理的对象修改后 代理类不会修改
 * 动态代理类是在运行的时候 动态的生成一个代理类 通过反射的方式调用方法的
 *
 * 基于jdk的动态代理
 * 1.必须实现InvocationHandler 这个接口
 * 2.被代理的对象的父类必须是接口 jdk动态代理是根据接口获取被代理的对象的所有的方法
 *
 */
public class JDKDynamicProxy implements InvocationHandler {

    //接口
    private Object object;

    public Object getInstance(Object target){

        object = target;
        Class<?> clazz = target.getClass();

        /**
         * public static Object newProxyInstance(
         * ClassLoader loader, 类加载器
         * Class<?>[] interfaces, 获取所有实现的接口
         * InvocationHandler h) 当前类 在生成的代理类中会调用线面InvocationHandler invoke方法 用来增强被代理对象
         */

       return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //增强操作
        before();

        Object o = method.invoke(object,args);

        //增强操作
        after();

        return o;
    }


    public void before(){
        System.out.println("调用之前增强!");
    }

    public void after(){
        System.out.println("调用之后增强!");
    }


}

3.CGLIB动态代理

委托类

package ProxyDemo.CGLIBProxy;

public class Shawn {

    public void findJob() {
        System.out.println("我要找工作!");
    }

}

CGLIB代理类

package ProxyDemo.CGLIBProxy;

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

import java.lang.reflect.Method;

/**
 * cglib 动态代理
 * 代理的对象 作为被代理对象的子类 通过子类调用父类的方法
 *
 * 会生成3个代理类
 * 1个类集成了被代理的对象
 * 另外两个类 生成了被代理类的所有的方法的
 * 调用的时候不需要反射调用 调用效率较JDK动态代理的快
 *
 */
public class CGLIBProxy implements MethodInterceptor {

    private Object object;

    public Object createCGLIBProxy(Object object){
        this.object = object;
        //创建对象
        Enhancer enhancer = new Enhancer();
        //设置代理的目标类 进行扩展
        enhancer.setSuperclass(this.object.getClass());
        //设置回调 在回调中拦截对目标方法的调用
        enhancer.setCallback(this);
        //设置类加载器
        enhancer.setClassLoader(this.object.getClass().getClassLoader());
        //创建代理对象
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        Object oo = methodProxy.invoke(object,objects);
        after();
        return oo;
    }

    public void before(){
        System.out.println("调用之前增强!");
    }

    public void after(){
        System.out.println("调用之后增强!");
    }
}

总结: 

      静态代理:自己实现代理类,代理之前代理类已经存在。缺点:不符合开闭原则,当你修改被代理对象的时候如增加或删除一个方法,代理对象也要做相应的修改。

    动态代理:是在运行的时候,生成代理对象的。符合开闭原则,被代理对象改变的时候,不需要修改代理类。

            JDK动态代理:java jdk提供的一个动态代理的方式。1.代理的对象必须实现接口,jdk动态代理是根据接口来获取所有被代理对象的方法 2.需要实现InvocationHandler这个接口,用来生成代理类。

           CGLIB代理:被代理类不需要实现接口,被代理类作为代理类的父类。而且可以代理委托类的任意非final修饰的public和protected方法

静态代理和动态代理的目的都是用来扩展被代理类的,都是以重写被代理类的方法的目的来实现的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值