设计模式之代理模式

1.静态代理:

为每个代理类生成一个代理对象

public interface IPerson {

    public void findLove();
}
public class Zhangsan implements IPerson {


    public void findLove() {
        System.out.println("儿子要求肤白貌美大长腿:{}");
    }

}

生成一个代理类,代理张三找对象

public class Zhanglaosan implements IPerson {
    private Zhangsan zhangsan;

    public Zhanglaosan(Zhangsan zhangsan) {
        this.zhangsan = zhangsan;
    }

    public void findLove() {
        System.out.println("老张开始物色。。。");
        zhangsan.findLove();
        System.out.println("开始交往。。。");
    }
}

测试一下:

public class Test {

    public static void main(String[] args) {
        Zhanglaosan zhanglaosan = new Zhanglaosan(new Zhangsan());
        zhanglaosan.findLove();


    }
}

每个代理类都要生成一个代理对象,十分麻烦,如果赵六要找对象,还得在写一个代理类

2.动态代理

动态代理分jdk的动态代理和cglib的动态代理,相对于静态代理,动态代理不需要为每个代理类生成单独的代理类

2.1 jdk动态代理

public interface IPerson {

    public void findLove();

    public void buyIure();
}
public class Zhangsan implements IPerson {


    public void findLove() {
        System.out.println("张三要求肤白貌美大长腿:{}");
    }

    public void buyIure() {
        System.out.println("10万");
    }
}
public class ZhaoLiu implements IPerson {

    public void findLove() {
        System.out.println("赵六要求有车有房,学历高。。。。");
    }

    public void buyIure() {
        System.out.println("99万");
    }
}

在这里插入代码片一个代理类,可以动态生成代理对象

public class JdkMeipo implements InvocationHandler {

    private IPerson target;

    public  IPerson getInstance(IPerson target) {
        this.target = target;
        Class<?> clazz = target.getClass();
        return (IPerson) Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }

    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("我是媒婆,正在开始物色。。");
    }

    private void after() {
        System.out.println("双方开始交往");
    }
}

测试一下:

public class Test {

    public static void main(String[] args) {
        JdkMeipo meipo = new JdkMeipo();
        IPerson zhangsan = meipo.getInstance(new Zhangsan());
        zhangsan.findLove();

        System.out.println("分割线---------------------");
        IPerson zhaoliu = meipo.getInstance(new ZhaoLiu());
        zhaoliu.findLove();

        zhaoliu.buyIure();

    }
}

2.2 cglib动态代理

public class Zhangsan  {


    public final void findLove() {
        System.out.println("张三要求肤白貌美大长腿:{}");
    }


}
public class CglibMeipo implements MethodInterceptor {

    private Object target;

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

    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        before();
        Object invoke = method.invoke(target, objects);
        after();
        return invoke;
    }
    private void before() {
        System.out.println("我是媒婆,正在开始物色。。");
    }

    private void after() {
        System.out.println("双方开始交往");
    }

}

测试一下:

public class TestCglib {

    public static void main(String[] args) {
        CglibMeipo cg = new CglibMeipo();
        Zhangsan zhangsan = (Zhangsan)cg.getInstace(new Zhangsan());
        zhangsan.findLove();

    }
}

优缺点:
1.都是采用生成字节码,重组成一个新的类
2:实现方式不同 Cglib是采用继承的方式,覆盖目标代理类的方法,目标代理类中用final 修饰的方法不会被扩展增强;
Jdk采用实现接口的方式,要求代理目标类必须实现一个接口
3.Jdk的实现方式调用更复杂,cglib更简单
4.效率上jdk的动态代理效率低,每次调用都会使用反射原理,比较耗时,cglib这种方式效率更高,没有用到反射

代理模式将代理对象与真实被调用的对象分离,一定程度上降低了系统的耦合度,易于扩展,在一定程度上起到了保护目标对象的作用,增强目标对象的职责。

3.Spring中如何选择代理模式的?

1.如果bean 有实现类,则采用jdk的动态代理,没有的话采用cglib的方式。
2.Spring中可以通过配置,强制使用cglib的代理方式 <aop:aspectj-autoproxy proxy-target-class=“true”/>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值