Spring的设计模式------>JDK中的动态代理与CjLib动态代理

早接触java设计模式时就了解过很多设计模式,记得我接触到的设计模式----->>>
单例模式
观察者设计模式
适配器模式
工厂设计模式
代理设计模式

本文主要写一些对于代理模式的理解

还是发一下以前写的代理模式

现在有一种情况.
例如:张扬属于老好人.也不差钱.马跃向张扬借了10000块.规定一年后还.一年之后.当张某再次向 马某讨债的时候.张某在无奈之下找到 范某.范某经营一家讨债公司.基本上手法:刀子。手枪
范某为了成功的把钱讨回来.准备好了笑道.绳索.钢筋.钢锯
马某害怕了.之后还钱
债讨回来了.范某要销毁罪证。
张某 -----范某------讨债

讨债工作由范某完成.但是真正的债主是张某.凡剖只是代理张某去完成讨债工作;所以在java中.我们将这种设计模式称为代理设计模式;

传统的纯java代码

interface Give {
	public void giveMoney();}
class RealGive implements Give {
	public void giveMoney() {
		System.out.println("还钱");	}}
class ProxyGive implements Give { // 讨债公司
	private Give give = null;
	public ProxyGive(Give give) {
		this.give = give;	}
	public void Before() {
		System.out.println("准备工具");	}
		public void giveMoney() {
				this.Before();
		this.give.giveMoney();// 代表真正讨债者完成讨债
		this.After();
	}
	public void After() {
		System.out.println("销毁罪证");
	}}
public class Nullable {
	public static void main(String args[]) {
		Give give = new ProxyGive(new RealGive());
		give.giveMoney();
	}
}

与时俱进一下,spring,换一个流程,张三要去吃饭,

public interface Court {
    void doCourt();
}


@Repository("people")
class People implements Court {
    @Value("张三")
    private String name;

    public People() {
    }

    public People(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void doCourt() {
        System.out.println(this.name + ":我是无罪的");
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service("law")
public class Law implements Court{
    @Autowired
    @Qualifier("people")
    private People people;
    @Override
    public void doCourt() {
        System.out.println("被告人"+people.getName()+"有不在场的证据");
        people.doCourt();
    }
}

import com.gavin.Proxy.Law;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "com.gavin")
public class testone {
    @Test
    public void test(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(testone.class);
        Law law = ac.getBean("law", Law.class);
        law.doCourt();
    }
}

原理基本是一样的,代理方和被代理方都是实现同一个接口,通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。

但是这种方式属于静态代理,这就说明我们的一个静态代理类只能代理一个类,并且还要事先知道我们要代理哪个类才能写代理类,如果我们有其他类还想使用代理那就必须再写一个代理类。然而在实际开发中我们是可能是有非常多的类是需要被代理的,并且事先我们可能并不知道我们要代理哪个类。所以如果继续使用静态代理反而会增加许多的工作量,并且效率低下,代码复用率也不好。

总结

1在不修改原有代码的 或者没有办法修改原有代码的情况下 增强对象功能 使用代理对象 代替原来的对象去完成功能
进而达到拓展功能的目的
2JDK Proxy 动态代理面向接口的动态代理 一定要有接口和实现类的存在 代理对象增强的是实现类 在实现接口的方法重写的方法
生成的代理对象只能转换成 接口的不能转换成 被代理类
代理对象只能增强接口中定义的方法 实现类中其他和接口无关的方法是无法增强
代理对象只能读取到接口中方法上的注解 不能读取到实现类方法上的注解

JDK中的动态代理----PROXY

动态代理两种实现方式-----
实现接口的
继承父类的
本质都是去覆写一些方法来完成代理;
再JDK中通过proxy来实现面向接口的代理;
还有一个第三方的 clib来实现面向父类的代理

代码实现------>>

准备,接口一个

public interface Dinner {
    void eat();
    void drink();
}

准备两个实现类


public class Person  implements Dinner{

    private String name;
    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void eat(String foodName) {
        System.out.println(name+"在吃"+foodName);
    }

    @Override
    public void drink() {
        System.out.println(name+"在喝啤酒");
    }
}

public class Student  implements Dinner{
    private String name;

    public Student() {
    }

    public Student(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void eat(String foodName) {
        System.out.println(name+"在吃"+foodName);
    }
    @Override
    public void drink() {
        System.out.println(name+"在喝雪碧");
    }
}

准备动态代理的实现

首先要了解Proxy类的API,
不妨来一起看一下

继承实现关系
public class Proxy extends Object implements Serializable

类描述:
Proxy提供静态方法来创建像实例一样的对象 接口,但允许自定义方法调用。 为某个接口创建代理实例

构造方法---->

protected Proxy​(InvocationHandler h)

构建一个新的 Proxy来自子类的实例 (通常是动态代理类)具有指定值 为其调用处理程序。

类中的方法---->>
在这里插入图片描述
下面就开始实践----->>


import org.junit.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {
    @Test
    public void test(){
   Dinner dinner= new Person("李二狗");
   //get a proxy Instance
//        args
       /* ClassLoader loader, ---classloader
        Class<?>[] interfaces,  --- interface
        InvocationHandler h   ----invoke method
        */
        //get classloader
        ClassLoader classLoader=dinner.getClass().getClassLoader();
        Class<?>[] interfaces = dinner.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object returnVal;
               if(method.getName().equals("eat")){
                   System.out.println("饭钱洗手");
                   returnVal = method.invoke(dinner, args);
                   System.out.println("饭后刷碗");
               }else{
                   returnVal= method.invoke(dinner,args);
               }

                return returnVal;
            }
        };
       Dinner dinner1 = (Dinner)Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
   dinner1.eat("米饭");
   dinner1.drink();
    }
}

代码解析----->>>
首先是两个是实现类,不做过多赘述,重点在于代理类

在这里插入图片描述

第三方CJLIB实现动态代理

在spring中引入了人第三方动态代理,所以直接导入spring核心包就可以了

cjlib是通过子类覆写父类方法来达到方法增强的目的;

举个例子
在这里插入图片描述

通过配置cjlib实现动态代理

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodeMartain

祝:生活蒸蒸日上!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值