Spring理论知识(Ⅱ)——Spring核心容器模块

news2024/9/21 19:01:48

Spring的组成

Spring由20个核心依赖组成,这20个核心依赖可以分为6个核心模块
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
请添加图片描述

本篇文章着重描述Spring核心容器模块,其中包含了spring-beans,spring-core,spring-context,spring-expression-language(SpEl),spring-context-support等依赖

1. Spring核心容器

1.1 Spring核心容器的依赖简介

Spring Core Container 是 Spring 框架的核心部分,它为整个 Spring 框架提供了基础设施和基本功能。Spring Core Container 负责管理 Spring 应用中的所有组件(如 Beans)的创建、配置和生命周期,并通过依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)等机制来促进松散耦合的设计。

Spring Core

核心功能模块:Spring Core 模块是整个 Spring 框架的基础,包含了依赖注入(DI)机制的实现。它定义了 Spring 的基础类和接口,如 BeanFactory 和 ApplicationContext,这些都是 Spring 应用的核心部分。
BeanFactory:BeanFactory 是 Spring 的核心接口,用于管理 Bean 的创建和配置。它提供了基本的 IoC(控制反转)功能,是所有 Spring 应用的基石。
ApplicationContext:ApplicationContext 是 BeanFactory 的一个扩展,它提供了更多的企业级功能,如事件传播、国际化、AOP 支持等。ApplicationContext 是 Spring 应用中的高级容器,用于更复杂的配置和管理。

Spring Beans

Bean 配置和管理:Spring Beans 模块用于管理和配置 Spring 应用中的 Bean。Bean 是 Spring 容器管理的对象,可以通过 XML、注解或 Java 配置类来定义和配置。
依赖注入:通过依赖注入机制,Spring 容器会自动将需要的依赖注入到 Bean 中,从而减少组件之间的耦合,使得代码更易于测试和维护。

Spring Context

ApplicationContext 扩展:Spring Context 模块是对 Core 和 Beans 模块的扩展,提供了更全面的框架功能。ApplicationContext 作为高级容器,在大型企业应用中非常常用。
注解驱动开发:Spring Context 支持注解驱动的依赖注入,可以通过注解如 @Component、@Service、@Repository 等来标识 Spring 管理的 Bean,并使用 @Autowired 来自动注入依赖。

Spring Expression Language (SpEL)

表达式语言支持:SpEL 是 Spring 提供的一种强大的表达式语言,可以在 XML 配置、注解或其他 Spring 配置中使用。SpEL 支持调用方法、访问属性、操作集合等,提供了极大的灵活性。

1.2 Spring核心容器的pom依赖

        <!--Spring核心容器-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>

spring-core

Spring Core 是 Spring 框架的核心模块,提供了所有其他 Spring 模块的基础功能。

1. 核心工具类:

StringUtils:处理字符串的工具类。
ObjectUtils:提供对象相关的工具方法。
ClassUtils:用于处理类加载和反射的实用方法。
CollectionUtils:用于处理集合的工具类。
Assert:提供常用的断言方法,方便进行前置条件的验证。

这些工具类在整个 Spring 框架和开发中广泛使用,提供了对基本操作的简化。

2. 资源抽象(Resource Abstraction):

Resource 接口 以及相关实现类(如 ClassPathResource、FileSystemResource、UrlResource 等),提供了一套统一的 API 来访问不同类型的资源(例如文件系统中的文件、类路径资源、URL 资源等)。
这种抽象使得应用程序可以轻松地在不同的资源位置之间切换,而不必修改业务逻辑。

3. 类型转换系统(Type Conversion System):

ConversionService 接口 提供了对类型转换的支持,允许在应用中轻松地进行类型转换。这在处理配置文件中的属性值或者注入时尤为重要。
还包括 PropertyEditor 支持,允许在需要时将字符串转换为复杂对象。

4. 环境抽象(Environment Abstraction):

Environment 接口 及其实现类,提供了对环境变量、系统属性和外部化配置的访问和管理。
PropertySource 和 PropertyResolver 接口帮助解析和管理配置属性,这些功能对于支持外部化配置和环境感知的应用程序至关重要。

5. 日志支持:

提供了对多种日志框架(如 Log4j、SLF4J)的抽象支持,允许应用程序在不同的日志实现之间切换而无需更改代码。

这里需要重点说明:spring-core本身并不提供对多种日志框架的支持,而是通过引入spring-jcl完成了这个功能;另外我们观察spring-jcl包的结构
在这里插入图片描述

包名居然是apache.commons.logging!这是因为spring团队对common.logging 进行了重写,所以包名还保留之前的apache.commons.logging

JCL的全称为: Jakarta commons-logging, 是apache公司提供的一个抽象的日志框架, 并不提供日志功能,若需要使用具体的日志则需要添加依赖的jar包,但是它没有维护了,所以spring团队自己重写推出了一个spring-jcl

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.0.2.RELEASE</version>
  <name>Spring Core</name>
  <description>Spring Core</description>
  <url>https://github.com/spring-projects/spring-framework</url>
  <organization>
    <name>Spring IO</name>
    <url>http://projects.spring.io/spring-framework</url>
  </organization>
  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <developers>
    <developer>
      <id>jhoeller</id>
      <name>Juergen Hoeller</name>
      <email>jhoeller@pivotal.io</email>
    </developer>
  </developers>
  <scm>
    <connection>scm:git:git://github.com/spring-projects/spring-framework</connection>
    <developerConnection>scm:git:git://github.com/spring-projects/spring-framework</developerConnection>
    <url>https://github.com/spring-projects/spring-framework</url>
  </scm>
  <issueManagement>
    <system>Jira</system>
    <url>https://jira.springsource.org/browse/SPR</url>
  </issueManagement>
  <dependencies>
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-buffer</artifactId>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>io.projectreactor</groupId>
      <artifactId>reactor-core</artifactId>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>io.reactivex.rxjava2</groupId>
      <artifactId>rxjava</artifactId>
      <version>2.1.6</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>io.reactivex</groupId>
      <artifactId>rxjava</artifactId>
      <version>1.3.4</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>io.reactivex</groupId>
      <artifactId>rxjava-reactive-streams</artifactId>
      <version>1.2.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>net.sf.jopt-simple</groupId>
      <artifactId>jopt-simple</artifactId>
      <version>5.0.4</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.13</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-reflect</artifactId>
      <version>1.1.61</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib</artifactId>
      <version>1.1.61</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jcl</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-bom</artifactId>
        <version>Bismuth-SR4</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
      <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-bom</artifactId>
        <version>4.1.17.Final</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

spring-beans

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>5.0.2.RELEASE</version>
  <name>Spring Beans</name>
  <description>Spring Beans</description>
  <url>https://github.com/spring-projects/spring-framework</url>
  <organization>
    <name>Spring IO</name>
    <url>http://projects.spring.io/spring-framework</url>
  </organization>
  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <developers>
    <developer>
      <id>jhoeller</id>
      <name>Juergen Hoeller</name>
      <email>jhoeller@pivotal.io</email>
    </developer>
  </developers>
  <scm>
    <connection>scm:git:git://github.com/spring-projects/spring-framework</connection>
    <developerConnection>scm:git:git://github.com/spring-projects/spring-framework</developerConnection>
    <url>https://github.com/spring-projects/spring-framework</url>
  </scm>
  <issueManagement>
    <system>Jira</system>
    <url>https://jira.springsource.org/browse/SPR</url>
  </issueManagement>
  <dependencies>
    <dependency>
      <groupId>javax.inject</groupId>
      <artifactId>javax.inject</artifactId>
      <version>1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>2.4.13</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-reflect</artifactId>
      <version>1.1.61</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib</artifactId>
      <version>1.1.61</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.yaml</groupId>
      <artifactId>snakeyaml</artifactId>
      <version>1.19</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
  </dependencies>
</project>

我们可以看到其中包含了spring-core的依赖

spring-beans在Spring 的 IoC(Inversion of Control,控制反转)容器中起着至关重要的作用。这个包主要用于管理和配置应用程序中的 Bean,它提供了 Bean 的定义、创建、配置和管理的功能,是 Spring IoC 容器的基础。

1. Bean定义与管理

BeanDefinition 接口:定义了 Bean 的元数据,如类名、作用域scope、属性依赖,延迟加载等。所有的 Bean 都有一个对应的 BeanDefinition,用来描述该 Bean 的配置和依赖关系。
在这里插入图片描述

BeanFactory 接口(最重要的接口):Spring IoC 容器的基础接口,定义了 Bean 的创建、获取、销毁等基本操作。

ApplicationContext 是 BeanFactory 的一个更高级的子接口,提供了更多功能。

任何实现了BeanFactory接口的实现类,都可以被认为是一个Spring IOC容器

BeanFactory是spring中提供的最简单最基本的容器;

BeanFactory只提供了IOC/DI的功能。

这个容器中最主要个方法就是getBean()方法

DefaultListableBeanFactory:BeanFactory 的常用实现类,支持 Bean 的自动装配和多种 Bean 定义。

2. Bean生命周期管理

BeanFactory已经提供了基本的bean生命周期管理的功能,还有一些其他接口

BeanPostProcessor 接口

提供了对 Bean 的初始化前后进行处理的机制。开发者可以通过实现这个接口,在 Bean 的创建过程中加入自定义的逻辑。


package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

public interface BeanPostProcessor {


	// 初始化前执行
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	// 初始化后执行
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

InitializingBean 接口

定义了一个 afterPropertiesSet() 方法,用于在Bean的属性设置完毕后执行自定义的初始化逻辑


package org.springframework.beans.factory;

public interface InitializingBean {

	// 初始化时执行
	void afterPropertiesSet() throws Exception;

}

SmartInitializingSingleton接口

提供在所有单例Bean实例化完成后的回调机制


public interface SmartInitializingSingleton {

	/**
	 * Invoked right at the end of the singleton pre-instantiation phase,
	 * with a guarantee that all regular singleton beans have been created
	 * already. {@link ListableBeanFactory#getBeansOfType} calls within
	 * this method won't trigger accidental side effects during bootstrap.
	 * <p><b>NOTE:</b> This callback won't be triggered for singleton beans
	 * lazily initialized on demand after {@link BeanFactory} bootstrap,
	 * and not for any other bean scope either. Carefully use it for beans
	 * with the intended bootstrap semantics only.
	 */

	// 
	void afterSingletonsInstantiated();

}

DisposableBean 接口

定义了 destroy() 方法,允许在 Bean 被销毁时执行自定义的清理逻辑。


package org.springframework.beans.factory;

public interface DisposableBean {

	void destroy() throws Exception;

}

BeanFactoryPostProcessor接口

用于在BeanFactory创建后,对其中的Bean定义进行修改。

@FunctionalInterface表示这是一个函数式接口,用匿名内部类实现接口时可以替换为Lambda表达式

@FunctionalInterface
public interface BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean factory after its standard
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

3. 依赖注入

PropertyAccessor 和 BeanWrapper 接口:提供了对 Bean 属性的设置和访问的功能,支持属性的自动注入。
AutowireCapableBeanFactory:扩展了 BeanFactory 接口,支持自动装配的 Bean 工厂,可以自动注入依赖。

4. 属性解析与配置

PropertyEditor 接口:用于将属性值从一种格式转换为另一种格式,通常用于配置文件中的字符串与实际类型(如数字、布尔值、日期等)之间的转换。
CustomEditorConfigurer:允许在 Spring 容器中注册自定义的 PropertyEditor,用于自定义属性的转换规则。

5. 事件处理

ApplicationEvent 和 ApplicationListener 接口:用于在 Spring 容器中发布和监听事件。spring-beans 包提供了事件发布和处理的基础机制,而更高级的事件处理通常由 ApplicationContext 来实现。

spring-context和spring-context-support

1. pom依赖分析

spring-context,核心是更高级的bean生命周期管理:ApplicationContext接口(BeanFactory的子接口)

<dependency>
      <groupId>javax.annotation</groupId>
      <artifactId>javax.annotation-api</artifactId>
      <version>1.3.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.ejb</groupId>
      <artifactId>javax.ejb-api</artifactId>
      <version>3.2</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.enterprise.concurrent</groupId>
      <artifactId>javax.enterprise.concurrent-api</artifactId>
      <version>1.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.inject</groupId>
      <artifactId>javax.inject</artifactId>
      <version>1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.interceptor</groupId>
      <artifactId>javax.interceptor-api</artifactId>
      <version>1.2.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.money</groupId>
      <artifactId>money-api</artifactId>
      <version>1.0.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>1.1.0.Final</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.xml.ws</groupId>
      <artifactId>jaxws-api</artifactId>
      <version>2.3.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>joda-time</groupId>
      <artifactId>joda-time</artifactId>
      <version>2.9.9</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.13</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.beanshell</groupId>
      <artifactId>bsh</artifactId>
      <version>2.0b5</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>2.4.13</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>5.4.2.Final</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-reflect</artifactId>
      <version>1.1.61</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib</artifactId>
      <version>1.1.61</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-instrument</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>

主要包含了spring-core,spring-beans,spring-expression,spring-instrument依赖

spring-context-support,主要是一些工具类,增强spring-context。包含本地缓存,spring事务等

<dependencies>
    <dependency>
      <groupId>com.github.ben-manes.caffeine</groupId>
      <artifactId>caffeine</artifactId>
      <version>2.6.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.activation</groupId>
      <artifactId>activation</artifactId>
      <version>1.1.1</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.cache</groupId>
      <artifactId>cache-api</artifactId>
      <version>1.0.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>javax.mail</groupId>
      <artifactId>javax.mail-api</artifactId>
      <version>1.6.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>net.sf.ehcache</groupId>
      <artifactId>ehcache</artifactId>
      <version>2.10.4</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.codehaus.fabric3.api</groupId>
      <artifactId>commonj</artifactId>
      <version>1.1.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.27-incubating</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>2.3.0</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
      <optional>true</optional>
    </dependency>
  </dependencies>
spring-context的主要内容分析

spring-context指的是spring上下文
Spring Context 你真的懂了吗

在计算机系统中,进程执行时有进程上下文,如果进程在执行的过程中遇到了中断,CPU 会从用户态切换为内核态(当然这个过程用户进程是感知不到的,由硬件来实现的),此时进程处于的进程上下文会被切换到中断上下文中,从而可以根据中断号去执行相应的中断程序。

通过上面这个例子我们可以发现,进程在执行程序(不管是用户程序,还是内核中的中断程序)时,都会依赖一个上下文,这个上下文由多种数据结构组成,可以提供我们运行时需要的一些数据和保存运行时的一些数据。那其实 spring-context 就可以理解对一个程序运行时所需要的一些数据结构的抽象表达。

上文中我们可以很清晰的看到caffeine的使用,用于本地缓存

创建好的bean会被存放到spring-context中定义的数据结构当中,也会存储在缓存当中

spring-context主要包括:

DefaultListableBeanFactory
这就是大家常说的 ioc 容器,它里面有很多 map、list。spring 帮我们创建的 singleton 类型的 bean 就存放在其中一个 map 中。我们定义的监听器(ApplicationListener)也被放到一个 Set 集合中。

BeanDefinitionRegistry

把一个 BeanDefinition 放到 beanDefinitionMap。

AnnotatedBeanDefinitionReader

针对 AnnotationConfigApplicationContext 而言。一个 BeanDefinition 读取器。

扩展点集合

存放 spring 扩展点(主要是 BeanFactoryPostProcessor、BeanPostProcessor)接口的 list 集合。

BeanFactory和ApplicationContext的联系
package org.springframework.context;

import org.springframework.beans.factory.HierarchicalBeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.lang.Nullable;

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
		
	@Nullable
	String getId();

	String getApplicationName();

	String getDisplayName();

	long getStartupDate();

	@Nullable
	ApplicationContext getParent();

	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

ListableBeanFactory接口继承了BeanFactory接口,所以ApplicationContext本质上是BeanFactory的孙子接口

ApplicationContext接口:Spring Context模块定义了ApplicationContext接口,该接口扩展自BeanFactory接口。通过ApplicationContext接口,可以获得更丰富的功能和特性,如国际化支持、事件发布机制、资源加载、AOP支持等。ApplicationContext接口是Spring应用程序的主要接口,它扩展了BeanFactory接口,提供了更高级别的功能和集成。

配置加载:Spring Context模块支持从多种配置源加载配置信息,包括XML配置文件、Java注解和Java代码方式等。通过Spring Core的支持,它可以解析和加载这些配置信息,并在IoC容器中创建相应的对象。

Bean的管理和生命周期:Spring Context模块通过扩展Spring Core,提供了更灵活和强大的Bean的管理和生命周期管理功能。它可以自动检测和管理Bean的依赖关系,完成依赖注入,并在合适的时机执行Bean的初始化和销毁操作。

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;


public interface BeanFactory {


	String FACTORY_BEAN_PREFIX = "&";
	
	Object getBean(String name) throws BeansException;

	<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;

	Object getBean(String name, Object... args) throws BeansException;

	<T> T getBean(Class<T> requiredType) throws BeansException;

	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	boolean containsBean(String name);
	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
	
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	
	String[] getAliases(String name);

}

BeanFactory不支持基于注解的依赖注入,只能用xml文件

public class BeanFactoryWithClassPathResourceTest {

    @Test
    public void createBeanFactoryAndCheckEmployeeBean() {
        Resource res = new ClassPathResource("beanfactory-example.xml");
        BeanFactory factory = new XmlBeanFactory(res);
        Employee emp = (Employee) factory.getBean("employee");

        assertTrue(factory.isSingleton("employee"));
        assertTrue(factory.getBean("employee") instanceof Employee);
        assertTrue(factory.isTypeMatch("employee", Employee.class));
        assertTrue(factory.getAliases("employee").length > 0);
    }
}

Spring Expression Language (SpEL)

spring-expression的pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>5.0.2.RELEASE</version>
  <name>Spring Expression Language (SpEL)</name>
  <description>Spring Expression Language (SpEL)</description>
  <url>https://github.com/spring-projects/spring-framework</url>
  <organization>
    <name>Spring IO</name>
    <url>http://projects.spring.io/spring-framework</url>
  </organization>
  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <url>http://www.apache.org/licenses/LICENSE-2.0</url>
      <distribution>repo</distribution>
    </license>
  </licenses>
  <developers>
    <developer>
      <id>jhoeller</id>
      <name>Juergen Hoeller</name>
      <email>jhoeller@pivotal.io</email>
    </developer>
  </developers>
  <scm>
    <connection>scm:git:git://github.com/spring-projects/spring-framework</connection>
    <developerConnection>scm:git:git://github.com/spring-projects/spring-framework</developerConnection>
    <url>https://github.com/spring-projects/spring-framework</url>
  </scm>
  <issueManagement>
    <system>Jira</system>
    <url>https://jira.springsource.org/browse/SPR</url>
  </issueManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>5.0.2.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

我们可以看到,spring-expression的pom依赖只有一个:spring-core

spring-expression简介

SpEL(Spring Expression Language)是Spring框架中用于表达式语言的一种方式。它类似于其他编程语言中的表达式语言,用于在运行时计算值或执行特定任务。

SpEL提供了一种简单且强大的方式来访问和操作对象的属性、调用对象的方法,以及实现运算、条件判断等操作。它可以被用于XML和注解配置中,可以用于许多Spring框架中的特性,如依赖注入、AOP、配置文件等。

SpEL表达式可以在字符串中进行定义,使用特殊的语法和符号来表示特定的操作。例如,可以使用 ${expression}来表示一个SpEL表达式,其中expression是具体的SpEL语句

SpEL支持各种操作和函数,包括算术运算、逻辑运算、条件判断、正则表达式匹配、集合操作等。它还支持访问上下文中的变量和参数,以及调用对象的方法

Spring-SpEL表达式超级详细使用全解

这些内容可以在后续的spring-boot中,application.yaml中得到体现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2079637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

摄像头设备问题如何检测

摄像头等智能设备的在线状态通常被视为其运作正常的表现。但在日常监控使用中&#xff0c;由于使用空间、网络环境、产品年限等原因&#xff0c;设备掉线、视频流无法正常获取、监控画面异常&#xff08;如花屏&#xff09;&#xff0c;以及存储介质&#xff08;如SD卡&#xf…

【Electron】Electron学习笔记

1.什么是 Electron&#xff1f; Electron 是一个跨平台桌面应用开发框架&#xff0c;开发者可以利用 HTML、CSS、JavaScript 等Web技术来构建桌面应用程序。它本质上是结合了 Chromium 和 Node.js&#xff0c;目前广泛用于桌面应用程序开发。例如&#xff0c;许多桌面应用都采…

算法学习-基础算法

基础算法 一.二分查找 1.模版 boolean check(int x) { }int search(int left, int right) {while (left < right) {int mid (left right) >> 1;if (check(mid)) {//满足条件&#xff0c;向寻找范围继续寻找&#xff0c;例如我要找更靠左的&#xff1a;r m right…

一次学校OJ 代码执行测试

前言 以前看过一篇Windows上搭OJ被C#打穿的文章&#xff0c;刚好测测学校的OJ。 这里没有过多的研究其余的可能利用点&#xff0c;仅仅是简单记录下过程&#xff0c;一些思路的启发。 测试过程 首先看支持的代码类型&#xff1a; 尝试了Java发现不能import&#xff0c;那J…

一文带你从零到实战,学会gcc和Makefile,多文件编译神器的使用与编写

目录&#xff1a; 目录&#xff1a; 一、什么是Makefile 1.1 makefile的作用&#xff1a; 1.2 makefile的基本组成&#xff1a; 二、Linux编译过程&#xff1a; 2.1 linux编译过程: 2.1.1 预处理&#xff08;Preprocessing&#xff09; 2.1.2 编译&#xff08;Compilation&am…

# 移动硬盘误操作制作为启动盘数据恢复问题

移动硬盘误操作制作为启动盘数据恢复问题 文章目录 移动硬盘误操作制作为启动盘数据恢复问题步骤一恢复原有数据 步骤二格式化并重新分区 注意注意先找数据恢复软件恢复数据&#xff0c;把之前移动硬盘或者U盘上的数据恢复到其它地址 步骤一 恢复原有数据 使用一些数据恢复软…

SpringBoot实现Word转PDF/TXT

背景 研发工作中难免会遇到一些奇奇怪怪的需求&#xff0c;就比如最近&#xff0c;客户提了个新需求&#xff1a;上传一个WORD文档&#xff0c;要求通过系统把该文档转换成PDF和TXT。客户的需求是没得商量的&#xff0c;必须实现&#xff01;承载着客户的期望&#xff0c;我开始…

培训第三十七天(Dockerfile与registry)

一、使用Dockerfile创建镜像 Dockerfile文件命令介绍&#xff1a; FORM 指定基础镜像为该镜像的最后修改版本 FROM < img:tag >指定基础镜像为该镜像的⼀个tag版本 MAINTAINER 指定镜像创建者&#xff0c;企业内部不⽤指定&#xff0c;对外发布也可以不指定 RUN 运⾏…

探索Python的Excel力量:openpyxl库的奥秘

文章目录 探索Python的Excel力量&#xff1a;openpyxl库的奥秘背景&#xff1a;为什么选择openpyxl&#xff1f;库简介&#xff1a;openpyxl是什么&#xff1f;安装指南&#xff1a;如何安装openpyxl&#xff1f;快速上手&#xff1a;五个基本函数实战演练&#xff1a;三个应用…

Python实现Word文档转换为图片(JPG、PNG、SVG等常见格式)例子解析

在Python中将Word文档转换为图片&#xff08;如JPG、PNG、SVG等格式&#xff09;可以通过多种库实现&#xff0c;例如Spire.Doc for Python和Aspose.Words for Python。以下是一些详细的代码示例&#xff0c;展示了如何使用这些库完成转换。 使用Spire.Doc for Python转换Word…

网络服务器及IO模型

网络服务器 单循环服务器&#xff1a;服务器在同一时刻只能响应一个客户端的请求 并发服务器模型&#xff1a;服务器在同一时刻可以响应多个客户端的请求 实现TCP并发服务器 1.多进程 2.多线程 3.IO多路复用&#xff1a; 为了解决进程或线程阻塞到某个 I/O 系统调用而出现的…

几种前端处理文本换行展示

文章目录 一、使用 CSS 的 white-space 属性二、使用 CSS 的 word-break 和 word-wrap 属性三、 使用 CSS 的 flex 布局和自动换行四、 使用overflow实现换行 一、使用 CSS 的 white-space 属性 可以将 white-space 属性设置为 pre-wrap 或 pre-line。 pre-wrap&#xff1a;保…

【STM32】FMC

FMC功能与FSMC类似&#xff0c;但比FSMC更强大&#xff0c;但仅在F4 / F7 / H7等高级一点的MCU上支持&#xff0c;F1不支持。虽然我的是F103&#xff0c;但顺便都看了。 大部分图片来源&#xff1a;正点原子HAL库课程 专栏目录&#xff1a;记录自己的嵌入式学习之路-CSDN博客 目…

数据结构学习:栈

栈的简介 栈&#xff08;Stack&#xff09;是限定仅在表尾进行插入租删除操作的线性表。 允许插入和删除的一端称为栈顶(top),另-端称为栈底(bottom) 不含任何数据元素的栈称为空栈 栈又称为后进先出的线性表,简称LIFO结构 栈的插入操作&#xff0c;也叫做进栈&#xff0c…

java JVM

JVM的组成 Java虚拟机&#xff08;JVM&#xff09;是执行Java字节码的运行时环境。它由以下几个主要部分组成&#xff1a; 1. **类加载器&#xff08;ClassLoader&#xff09;**&#xff1a; - 负责加载Java类的字节码到JVM中&#xff0c;并进行链接和初始化。 关于Java的…

C++基础练习

1》提示并输入一个字符串&#xff0c;统计该字符串中字母个数、数字个数、空格个数、其他字符的个数 1 #include<iostream>2 using namespace std;3 4 int main()5 {6 string str1; //定义字符串数据7 cout << "请输入一个字符串>>>" ;8…

三种常用的Word打印部分内容操作技巧

作为打工人&#xff0c;我们经常需要处理Word文档&#xff0c;有时还会遇到只需要打印文档中的部分内容而非整个文档的情况。为了高效地完成这一任务&#xff0c;Word提供了多种灵活的设置方法。本文将详细介绍三种常用的方法来帮助你实现只打印Word文档中的部分内容。 方法一&…

第一周学习--联邦学习

OUC读研--第一周 目录 1、课程学习 2、fedavg的算法实现 关于代码详解 1、client __init__ 方法 local_train 方法 2、server 3、get_dataset 函数定义 数据集加载 MNIST 数据集 CIFAR-10 数据集 返回值 使用示例 4、 main 代码解释 可能的改进点 5、models …

机器学习之 K-means算法的代码实现

K-means 算法简介 K-means 是一种常用的无监督学习算法&#xff0c;主要用于数据聚类。它的主要思想是将数据集中的数据分成 K 个簇&#xff08;Cluster&#xff09;&#xff0c;使得簇内的数据点尽可能相似&#xff0c;而簇间的差异尽可能大。K-means 算法的核心步骤包括初始…

关于类与构造函数继承的小挑战

题目 /* 使用构造函数将电动汽车&#xff08;称为 EV&#xff09;作为 Car 的子 “类 ”来实现。除了品牌和当前速度外&#xff0c;EV 还具有当前电池电量&#xff08;百分比&#xff09;&#xff08;“charge ”属性&#xff09;&#xff1b;实现一个 “chargeBattery ”方法…