Springboot源码 TargetSource解析

yizhihongxing

Springboot源码 TargetSource解析

概述

在Spring框架中,AOP的核心就是AOP代理,而AOP代理的核心就是代理对象,而代理对象有可能是动态生成的,也有可能是预先存在的,在Spring框架中,预先存在的代理对象称为静态代理对象,动态生成的代理对象则使用CGLIB和JDK动态代理技术来实现,这里我们主要介绍CGLIB动态代理实现的过程。

Spring中使用CGLIB来对目标对象进行代理,生成的动态代理对象通常继承自目标对象的类型,同时又动态增加了一些方法用于实现增强逻辑。

TargetSource是Spring框架中一个非常重要的概念,用于描述代理对象和目标对象之间的关系。Spring中使用的代理分为两类,JDK动态代理和CGLIB动态代理,TargetSource就是用来描述这两种代理对象和原对象之间的关系,从而为代理对象提供目标对象的详细信息。

TargetSource

在Spring中,TargetSource是一个接口,声明了两个方法:

public interface TargetSource {

    Class<?> getTargetClass();

    Object getTarget() throws Exception;

    void releaseTarget(Object target) throws Exception;
}

其中getTargetClass方法用于获取目标对象的Class类型,getTarget方法用于获取目标对象实例,releaseTarget方法则用于释放目标对象实例,在代理方法正常执行结束或意外异常结束时,都需要调用该方法释放目标对象,以便下次使用。

被代理对象的生成

下面我们通过一个Product类实现一个简易版的CGLIB动态代理示例,代码如下:

public class Product {
    private String name;

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

    public String getName() {
        return name;
    }

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

在代理代码中,我们需要借助CGLIB库才能生成一个代理对象,因此需要在pom.xml文件中加入以下依赖:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

代理类的生成过程如下:

public class ProductProxyFactory {
    public static Product getProductProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Product.class);
        enhancer.setCallback(new ProductMethodInterceptor());
        return (Product) enhancer.create();
    }
}

在以上代码中,我们使用了Enhancer类对Product类进行了代理,同时为代理对象设置了回调,回调类为ProductMethodInterceptor。

方法拦截器

方法拦截器是代理对象和原对象之间桥梁,负责对代理对象的方法进行增强,CGLIB动态代理为每个代理类都提供了一个MethodInterceptor接口,用于实现方法拦截器的相关逻辑。以下是一个简单的示例:

public class ProductMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("before " + method.getName() + " invoked");
        Object result = methodProxy.invokeSuper(object, args);
        System.out.println("after " + method.getName() + " invoked");
        return result;
    }

}

在以上代码中,我们对Product类的所有方法进行了拦截,并在拦截器中在方法前后加了一些日志输出,以便于观察代理对象和原对象之间的交互。

示例说明

示例1:获取目标对象类名

public class Main {

    public static void main(String[] args) {
        Product product = new Product("手机");
        TargetSource targetSource = new SingletonTargetSource(product);
        System.out.println(targetSource.getTargetClass().getName());
    }

}

在以上示例中,我们创建了一个Product类的实例,然后将其包装成一个TargetSource对象,使用SingletonTargetSource实现,最后获取TargetSource的类名。

示例2:获取目标对象实例

public class Main {

    public static void main(String[] args) {
        Product product = new Product("手机");
        TargetSource targetSource = new SingletonTargetSource(product);
        try {
            Object result = targetSource.getTarget();
            System.out.println(((Product) result).getName());
            targetSource.releaseTarget(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

在以上示例中,我们创建了一个Product类的实例,然后将其包装成一个TargetSource对象,使用SingletonTargetSource实现,最后获取TargetSource的实例对象,并调用Product类的getName方法输出结果,最后需要调用releaseTarget方法释放目标对象。

总结

TargetSource是Spring框架中描述动态代理与原对象之间关系的接口,它提供了获取目标对象类名和实例对象的方法,同时也提供了释放目标对象实例的方法,以便于下次使用。通过以上示例,我们可以了解到Spring如何使用CGLIB动态代理生成代理对象,同时也了解了TargetSource在代理对象和原对象之间的联系,为后续深入了解Spring的AOP技术打下基础。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springboot源码 TargetSource解析 - Python技术站

(0)
上一篇 2023年5月30日
下一篇 2023年5月30日

相关文章

  • Java实现学生管理系统(控制台版本)

    Java实现学生管理系统的控制台版本是一个常见的练手项目,同时也是Java编程语言的入门级别的练习项目,其主要目的是通过实现一个简单的学生信息管理系统来训练Java编程的基本能力。 以下是实现Java学生管理系统的大致步骤: 1. 设计学生类 学生类是整个学生信息管理系统的核心,需要包含学生的基本信息,例如姓名、学号、性别、年龄等。 示例代码: public…

    Java 2023年5月19日
    00
  • spring注解 @PropertySource配置数据源全流程

    Spring注解 @PropertySource 用于加载指定的属性源,是Spring Framework 4.0版本之后提供的新特性。它允许我们从外部文件或环境变量中读取配置信息,灵活地管理我们的应用程序的数据源。 下面是使用 @PropertySource 配置数据源的完整流程: 引入依赖 在项目的 pom.xml 文件中添加以下依赖: <depe…

    Java 2023年6月2日
    00
  • java 一键部署 jar 包和 war 包

    一键部署是指通过单击一个按钮或执行一个脚本就可以完成整个软件部署的过程,这在提高开发效率以及方便用户安装等方面具有重要的意义。下面我来详细讲解“Java 一键部署 jar 包和 war 包”的完整攻略。 一、jar 包的一键部署 Java 编写的应用程序一般打成 jar 包进行部署。在进行 jar 包一键部署时,可以通过以下步骤实现: 1. 建立 Maven…

    Java 2023年5月24日
    00
  • Java中Arrays的介绍及使用方法示例

    Java中Arrays的介绍及使用方法示例 1. 什么是Arrays 在Java编程语言中,Arrays是一个类,用来操作数组的工具类,包含了一些静态方法,如排序和二分查找等。 2. Arrays的常用方法 2.1 初始化数组 Arrays类提供的最常用的初始化数组的方法是:Arrays.fill(),可以用来填充一个数组。 // 初始化长度为10的数组,全…

    Java 2023年5月26日
    00
  • java输出镂空金字塔实现案例

    下面是实现java输出镂空金字塔的完整攻略。 需求说明 我们需要实现一个程序,能够打印出指定层数的镂空金字塔。例如,当我们指定金字塔总层数为5时,程序应该输出如下图所示的镂空金字塔: * * * * * * * * * * * * * * * * * * * * * * * * 实现步骤 确定金字塔的总层数n,同时计算出金字塔每一层的空格数和星号数。空格数的…

    Java 2023年5月26日
    00
  • Jsp+Servlet实现简单登录注册查询

    下面是详细的“Jsp+Servlet实现简单登录注册查询”的攻略: 一、前提要求:开发环境安装与配置 1. JDK和Tomcat环境安装 在开始之前,需要在电脑上安装JDK和Tomcat两个环境。 JDK下载安装地址:https://www.oracle.com/java/technologies/javase-downloads.html Tomcat下载…

    Java 2023年6月15日
    00
  • Hibernate实现悲观锁和乐观锁代码介绍

    关于Hibernate实现悲观锁和乐观锁的代码介绍,我们可以分别针对不同的锁机制进行讲解。 一、悲观锁 悲观锁机制在操作数据的时候会先将数据锁定,避免其他线程对该数据的访问和修改。Hibernate提供了两种方式实现悲观锁:使用数据库相关功能实现和使用Hibernate API实现。 1.使用数据库相关功能实现悲观锁 需要在sql语句中使用 for upda…

    Java 2023年5月20日
    00
  • 详解Java的Spring框架中的注解的用法

    关于详解Java的Spring框架中的注解的用法的攻略,我们来逐步分析。 1. Spring框架注解概述 Spring框架注解是用来装饰Java类、接口、方法和属性等元素的特殊标记。它们可以提供元数据,此元数据可以被Spring容器用来自动装配应用程序中的组件。 例如,@Autowired是最常用的Spring框架注解之一,它可以用于自动装配其他bean或者…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部