Spring代理模式

简介: Spring代理模式

代理有静态代理、动态代理和cglib代理

静态代理:1.目标类必须实现一个接口,比如dao层的先写一个接口,再写一个接口的dao实现类,静态代理就是对这个实现类进行代理
                 2. 必须实现和目标对象(需要代理的类的对象)一样的接口,就是这个目标对象实现了什么接口,静态代理类就必须实现什么接口
弊端:如果目标类方法太多岂不是所有的方法都要写一下?太麻烦

静态代理
public class UserDaoProxy implements IUserDao{

    // 接收保存目标对象
    private IUserDao target;
    public UserDaoProxy(IUserDao target) {
        this.target = target;
    }

    @Override
    public void save() {
        System.out.println("开始事务...");

        target.save();             // 执行目标对象的方法

        System.out.println("提交事务...");
    }
}


动态代理:1.和静态代理一样也是目标类必须实现接口
                  2.代理类不用必须实现和目标类一样的接口,是一个方法,给里面有三个参数,有一个参数是要指定目标类实现接口的类型,(注意指明的是实现接口的类型)

动态代理
public class ProxyFactory {

    // 维护一个目标对象
    private Object target;
    public ProxyFactory(Object target){
        this.target = target;
    }

    // 给目标对象,生成代理对象  
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        System.out.println("开启事务");

                        // 执行目标对象方法
                        Object returnValue = method.invoke(target, args);

                        System.out.println("提交事务");
                        return returnValue;
                    }
                });
    }
}


cglib代理:1.目标类没有实现的接口,是以子类的形式代理!
                   2.如果你又不想像静态代理那样实现相同的接口重写所有的方法,也不想像动态代理那种指明接口类型或者说目标对象根本没有实现接口
                   3.用cglib的方法可以实现,两个方法,看下面代码。
                    4.使用cglib代理的话是需要导包的,cglib.jar,但是spring-core.jar包中里面有引入这个cglib.jar的包,也就是导了spring的包就可以用了。
cglib代理
public class ProxyFactory implements MethodInterceptor{
    // 维护目标对象
    private Object target;
    public ProxyFactory(Object target){
        this.target = target;
    }

    // 给目标对象创建代理对象
    public Object getProxyInstance(){
        //1. 工具类
        Enhancer en = new Enhancer();
        //2. 设置父类
        en.setSuperclass(target.getClass());
        //3. 设置回调函数
        en.setCallback(this);
        //4. 创建子类(代理对象)
        return en.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {

        System.out.println("开始事务.....");

        // 执行目标对象的方法
        Object returnValue = method.invoke(target, args);

        System.out.println("提交事务.....");

        return returnValue;
    }
}


spring中的代理模式:根据目标对象是否有实现接口动态的选择代理的模式。
                                    1.如果目标类有实现的接口就使用动态代理
                                    2.如果目标类没有实现的接口就使用cglib代理

 为什么上层向下层提供的是接口支持,而不是具体的实现类?

  这里面涉及到spring中的事务管理,是aop方式,aop又涉及到代理,代理分为三种,静态、动态、cglib代理。
  具体三种代理的区别和实现上面展示了
  这里值得一说的是如果你用动态代理需要告诉spring一个被代理类的父类对象,动态代理是以目标类子类的形式代理;
  如果使用cglib代理被代理类是要继承接口的。

  换个角度看,如果你的dao或者service层写了接口定义方法,实体类是实现这个接口,那么spring就给你采用cglib代理,
  如果你的dao或者service层是直接写实现类,那么spring就给你采用jdk动态代理
  所以写代码时要细心点,比如说如果你写具体实现类是实现接口,spring给你采用cglib代理,
  你糊涂的在下层调用和注入的时候是直接用实现类,
  那么是会报错的,因为你告诉spring用cglib代理,而你在下层用的时候用jdk动态代理,肯定冲突啊。
  

                

目录
相关文章
|
4月前
|
Java Spring
Spring5源码(38)-SpringAop代理调用过程(二)
Spring5源码(38)-SpringAop代理调用过程(二)
38 0
|
4月前
|
Java Spring
Spring5源码(37)-SpringAop代理调用过程(一)
Spring5源码(37)-SpringAop代理调用过程(一)
35 0
|
4月前
|
缓存 Java Spring
Spring5源码(35)-SpringAop创建代理(一)
Spring5源码(35)-SpringAop创建代理(一)
34 0
|
29天前
|
缓存 安全 Java
Spring AOP 中两种代理类型的限制
【8月更文挑战第22天】
14 0
|
29天前
|
Java Spring
|
30天前
|
安全 Java 开发者
|
30天前
|
安全 Java 测试技术
Spring Security 中的委托过滤器代理
【8月更文挑战第21天】
13 0
|
2月前
|
缓存 安全 Java
Spring高手之路21——深入剖析Spring AOP代理对象的创建
本文详细介绍了Spring AOP代理对象的创建过程,分为三个核心步骤:判断是否增强、匹配增强器和创建代理对象。通过源码分析和时序图展示,深入剖析了Spring AOP的工作原理,帮助读者全面理解Spring AOP代理对象的生成机制及其实现细节。
31 0
Spring高手之路21——深入剖析Spring AOP代理对象的创建
|
4月前
|
设计模式 运维 Java
Spring5深入浅出篇:Spring中静态代理与动态代理
Spring框架中的代理模式分为静态代理和动态代理。在JavaEE分层开发中,Service层最为重要,包含核心业务逻辑和额外功能。静态代理通过手动创建代理类来增加原始类的额外功能,但当代理类数量多时管理不便且不易于维护。动态代理则解决了这一问题,通过Spring的AOP(面向切面编程)实现,无需手动创建代理类,只需定义切点和增强(额外功能),在运行时动态生成代理对象,提高了代码的灵活性和可维护性。动态代理主要利用了JVM的字节码技术,在运行过程中创建代理类,执行完毕后随着虚拟机的结束而销毁,不会产生持久化的代理类。
|
4月前
|
设计模式 安全 Java
深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南
深入理解Spring Boot AOP:CGLIB代理与JDK动态代理的完全指南
1309 1