栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【Spring】动态代理开发详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Spring】动态代理开发详解

这里写目录标题
  • 一、搭建开发环境
  • 二、Spring 动态代理的开发
    • 2.1 创建原始对象(目标对象)
    • 2.2 额外功能`MethodBeforeAdvice`接口
    • 2.3 定义切入点
    • 2.4 组装
    • 2.5 调用
  • 二、动态代理细节分析
  • 三、动态代理开发详解
    • 3.1 MethodBeforeAdvice
    • 3.2 MethodInterceptor(方法拦截器)


概念:通过代理类为原始类(目标类)增加额外功能
好处:利于原始类(目标类)的维护

一、搭建开发环境

  org.springframework
  spring-aop
  5.1.14.RELEASE


  org.aspectj
  aspectjrt
  1.8.9


  org.aspectj
  aspectjweaver
  1.8.13

二、Spring 动态代理的开发 2.1 创建原始对象(目标对象)
public interface UserService {
    void register(User user);
    boolean login(String name, String password);
}
public class UserServiceImpl implements UserService {
    @Override
    public void register(User user) {
        System.out.println("UserServiceImpl.register 业务运算 + DAO");
    }

    @Override
    public boolean login(String name, String password) {
        System.out.println("UserServiceImpl.login 业务运算 + DAO");
        return true;
    }
}
2.2 额外功能MethodBeforeAdvice接口
public class Before implements MethodBeforeAdvice {
    
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("---method before advice log---");
    }
}


2.3 定义切入点

切入点:额外功能的加入
目的: 由程序员根据自己的需要,决定额外功能加入给哪个原始方法(register、login)


    

2.4 组装

步骤二、步骤三进行整合。


	
	
    
    

    
    
   
    
        
        
        
    

2.5 调用

目的:获得 Spring 工厂创建的动态代理对象,并进行调用
注意:
Spring 的工厂通过原始对象的 id 值获得的是代理对象
获得代理对象后,可以通过声明接口类型,进行对象的存储

@Test
public void test1() {
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
    UserService userService = (UserService) ctx.getBean("userService");
    userService.login("admin", "1234");
    userService.register(new User());
}
二、动态代理细节分析

Spring 创建的动态代理类在哪里?

Spring 框架在运行时,通过动态字节码技术,在 JVM 创建的,运行在 JVM 内部,等程序结束后,会和 JVM 一起消失。

什么是 动态字节码技术?

通过第三方动态字节码框架,在 JVM 中创建对应类的字节码,进而创建对象,当虚拟机结束,动态字节码跟着消失。

结论:

动态代理不需要定义类文件,都是 JVM 运行过程中动态创建的;
所以不会造成静态代理的缺点:类⽂件数量过多,影响项目管理的问题。

  • 动态代理编程简化代理的开发:在额外功能不改变的前提下,创建其他目标类(原始类)的代理对象时,只需要指定原始(目标)对象即可。
  • 动态代理使得额外功能的维护性大大增强。
三、动态代理开发详解 3.1 MethodBeforeAdvice

MethodBeforeAdvice接口作用:额外功能运行在原始方法执行之前,进行额外功能操作。

public class Before implements MethodBeforeAdvice {
    
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("---new method before advice log---");
    }
}

3.2 MethodInterceptor(方法拦截器)

methodInterceptor 接口:额外功能可以根据需要运行在原始方法执行前、执行后以及执行的前后。

  • 参数:MethodInvocation:额外功能所增加给的那个原始方法 (login, register)
  • 返回值:Object:原始方法的返回值 (没有就返回 null)
  • invocation.proceed():原始方法运行

额外功能运行在原始方法之前:

public class Around implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("---额外功能运行在原始方法执行之前---");
        Object ret = methodInvocation.proceed(); // 原始方法运行, 获取原始方法的返回值
        return ret;
    }
}

额外功能运行在原始方法 之后:

public class Around implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Object ret = methodInvocation.proceed(); // 原始方法运行, 获取原始方法的返回值
        System.out.println("---额外功能运行在原始方法执行之后---");
        return ret;
    }
}

额外功能运行在原始方法前后:

public class Around implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
    	System.out.println("---额外功能运行在原始方法执行之前---");
        Object ret = methodInvocation.proceed(); // 原始方法运行, 获取原始方法的返回值
        System.out.println("---额外功能运行在原始方法执行之后---");
        return ret;
    }
}

额外功能运行在原始方法抛出异常的时候:

public class Around implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Object ret = null;
        try {
            ret = methodInvocation.proceed(); // 原始方法运行, 获取原始方法的返回值
        } catch (Throwable throwable) {
            System.out.println("---额外功能运行在原始方法抛异常的时候---");
        }
        return ret;
    }
}

MethodInterceptor影响原始方法的返回值:

public class Around implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("---log---");
        Object ret = methodInvocation.proceed();
        return false;
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284223.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号