深度挖掘Spring IoC核心模块源码的宝藏

简介: 深度挖掘Spring IoC核心模块源码的宝藏

Spring 通过配置文件加载 Bean


开始本文的内容之前你得要搭建好 Spring 源码的环境,不会搭建的可以去查阅查阅我之前写的 Spring源码编译

在 resources 当中创建配置文件 spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>


在配置文件当中添加配置:

<bean id="userService" class="top.it6666.service.UserServiceImpl"/>


在工程当中创建业务类:


UserService.java

/**
 * @author yby6
 * @program spring
 * @date Created in 2023/9/29 029 11:39
 * @description
 **/
public interface UserService {
   /**
    * 显示
    */
   void show();
}

UserServiceImpl.java

/**
 * @author yby6
 * @program spring
 * @date Created in 2023/9/29 029 11:40
 * @description
 **/
public class UserServiceImpl implements UserService {
   @Override
   public void show() {
      System.out.println("Hello Spring");
   }
}




验证


在测试类当中,编写创建容器,获取 Bean,进行测试:

/**
 * @author yby6
 * @program spring
 * @date Created in 2023/9/29 029 11:42
 * @description
 **/
public class SpringTest {
   public static void main(String[] args) {
      ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:spring-config.xml");
      UserService userService = (UserService) applicationContext.getBean("userService");
      userService.show();
   }
}





Spring 通过注解加载 Bean


在测试类上添加注解 @Configuration包扫描

在业务类上方添加 Spring 相关注解注入到 Spring IOC 容器当中:




验证


更改之前的测试类,通过注解加载容器,获取 Bean 元素:

public static void main(String[] args) {
   // 通过注解获取容器
   AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringTest.class);
   UserService userService = (UserService) applicationContext.getBean("userServiceImpl");
   userService.show();
   UserController userController = (UserController) applicationContext.getBean("userController");
   userController.showMethod();
   System.out.println("===========================");
   // 扩展内容,可以通过上下文对象获取所有管理的Bean name,通过getBeanDefinitionNames()获取
   String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
   for (String beanDefinitionName : beanDefinitionNames) {
      System.out.println(beanDefinitionName);
   }
}

整体流程,解析配置,定位与注解对象,注入对象,无论是通过 xml 还是注解的方式都需要经过解析和加载然后在注入对象放入到 IOC 容器当中




Spring 中常见配置


关于 bean

在 Spring 当中一切都是围绕 Bean 进行,Bean 本质就是 Java 对象, 平时由我们自己来进行创建, 有了 Spring 后, Bean 的创建全部交给了 Spring,不需要在原来创建 Bean 的地方添加任何的额外信息,这些额外的信息全部通过配置文件进行控制。

关于:BeanDefinition,在 Spring 运行过程当中,会根据配置生成用来描述 Bean 的 BeanDefinition




作用范围


  • @Scope

关于取值:

  • singleton
  • prototype
  • request
  • session
  • globalsession




懒加载

  • @Lazy

定义 Bean 是否为延时加载, 如果为 true 会在真正使用 Bean 的时候才加载




首选


  • @Primary

值为 true,Bean 会优先实现类,如果按照类型装配时,如果存在一个接口对应多个实现类,多个实现类中被 Primary 为 true 的类会优先当做接口的实现类进行装配

还可以通过 Factory-bean 和 Factory-method(@configuration 和 @Bean) 从工厂 Bean 或工厂方法当中获取 Bean。





Bean 配置演示


创建 entity 包,在该包中创建实体类 Student:

在 xml 配置文件当中添加配置:

<bean id="student" class="top.it6666.entiry.Student"
     scope="singleton"
/>


验证:

public static void main(String[] args) {
   ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:spring-config.xml");
   for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {
      System.out.println(beanDefinitionName);
   }
   Student student1 = (Student) applicationContext.getBean("student");
   Student student2 = (Student) applicationContext.getBean("student");
   System.out.println(student1);
   System.out.println(student2);
}


如上的 bean 配置添加了 scope 并且配置为了单例所以创建出来的对象内存地址都是同一个,在来看看  Primary 当一个接口存在多个实现类会优先注入为 true 的实现类,先来看这一点吧,再次新建一个实现类 QqUserServiceImpl.java:

/**
 * @author yby6
 * @program spring
 * @date Created in 2023/9/28 028 14:28
 * @description
 **/
@Service
public class QqUserServiceImpl implements UserService {
   @Override
   public void show() {
      System.out.println("QQ用户");
   }
}


修改 xml 添加配置:

<bean id="qqUserService" class="top.it6666.service.QqUserServiceImpl"
     primary="true"
/>


验证方式:

public static void main(String[] args) {
   ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:spring-config.xml");
   UserService userService = applicationContext.getBean(UserService.class);
   userService.show();
}

关于懒加载,目前利用 UserServiceImpl.java 测试懒加载,明确的实现 UserServiceImpl.java 的默认无参构造函数,在当中加一句打印代码:


紧接着修改 xml 配置文件添加懒加载配置,然后我们在运行测试类代码进行测试,如果打印了刚刚我们添加的打印信息就说明 Spring 已经加载了,没有打印就说明没有其他地方使用该资源,没有进行加载:


<bean id="userService" class="top.it6666.service.UserServiceImpl" lazy-init="true"/>

运行测试类:


并没有打印我们添加的日志信息所以说明没有加载,已经达到了懒加载效果,也就是延时加载的效果,我们在来看看使用了 UserServiceImpl.java 之后它的效果又是如何呢修改 QqUserServiceImpl.java:


/**
 * @author yby6
 * @program spring
 * @date Created in 2023/9/28 028 14:28
 * @description
 **/
@Service
public class QqUserServiceImpl implements UserService {
   private UserServiceImpl userServiceImpl;
   public void setUserServiceImpl(UserServiceImpl userServiceImpl) {
      this.userServiceImpl = userServiceImpl;
   }
   public UserServiceImpl getUserServiceImpl() {
      return this.userServiceImpl;
   }
   @Override
   public void show() {
      System.out.println("QQ用户");
   }
}


在 xml 当中进行属性注入:

<bean id="qqUserService" class="top.it6666.service.QqUserServiceImpl"
     primary="true"
>
   <property name="userServiceImpl" ref="userService"/>
</bean>


运行测试类代码:


创建 factory 包,在该包下创建 StudentFactory 类:


/**
 * @author yby6
 * @program spring
 * @date Created in 2023/9/28 028 14:00
 * @description
 **/
public class StudentFactory {
   public static Student getStudent() {
      return new Student();
   }
}


使用静态工厂创建实例(factory-method):

<bean id="student" class="top.it6666.factory.StudentFactory"
     factory-method="getStudent"
     scope="singleton"
/>


验证方式同上:




使用 FacotoryBean 创建对象


在 factory 包中创建 StudentFacotory,其实在如上我们已经创建该类,不一样的就是类当中 getStudent 方法是静态的,现在我们改为非静态方法如下:

创建过程,需要先创建 FactoryBean 对象,再通过该对象调用里面的方法进行创建 Bean。

<bean id="studentFactory" class="top.it6666.factory.StudentFactory"/>
<bean id="studentThree"
     factory-bean="studentFactory"
     factory-method="getStudent"
/>


测试验证一下,测试结果如下:

目前还没有讲解到关于 Spring IOC 源码的边缘,因为博主的想法就是想将该内容分为许多的小文章进行一一发布,所以这里就先简单的介绍一下 IOC 相关的内容就相当于一个回顾吧





最后


本期结束咱们下次再见👋~

🌊 关注我不迷路,如果本篇文章对你有所帮助,或者你有什么疑问,欢迎在评论区留言,我一般看到都会回复的。大家点赞支持一下哟~ 💗

相关文章
|
25天前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
7月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
485 26
|
5月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
373 70
|
4月前
|
安全 Java API
Spring Boot 功能模块全解析:构建现代Java应用的技术图谱
Spring Boot不是一个单一的工具,而是一个由众多功能模块组成的生态系统。这些模块可以根据应用需求灵活组合,构建从简单的REST API到复杂的微服务系统,再到现代的AI驱动应用。
|
4月前
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
|
9月前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
187 69
|
6月前
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
6月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
111 0
|
9月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能