学一学Spring中的@Value

Spring版本: 5.3.27

JDK版本: 1.8

1、MyConfig.properties何时被加载解析?

2、MyService中的两个@Value何时解析?

3、MyService中的两个@Value何时注入属性文件中的值?

一、样例

服务类

kotlin 复制代码
 package com.lazy.snail.service;
 ​
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 ​
 /**
  * @ClassName MyService
  * @Description TODO
  * @Author lazysnail
  * @Date 2024/10/17 11:42
  * @Version 1.0
  */
 @Service
 public class MyService {
     @Value("${blog.host}")
     private String host;
 ​
     @Value("${blog.email}")
     private String email;
 ​
     public void printEmail() {
         System.out.println(this.email);
     }
 }
 ​

属性配置文件

ini 复制代码
 #MyConfig.properties
 blog.host=https://lazysnailstudio.com/
 blog.email=lazy_snail@aliyun.com

主配置类

less 复制代码
 @Configuration
 @PropertySource(value = "classpath:MyConfig.properties")
 @ComponentScan(basePackages = "com.lazy.snail")
 public class AppConfig {
 ​
 }

测试类

java 复制代码
 package com.lazy.snail;
 ​
 import com.lazy.snail.service.MyService;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 ​
 @Slf4j
 public class SpringTest {
 ​
     @Test
     void test() {
         ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
         context.getBean(MyService.class).printEmail();
     }
 }
 ​

二、样例分析

1、new AnnotationConfigApplicationContext(AppConfig.class)

创建容器、注册内部bean定义信息、注册配置类bean定义信息

refresh之前容器中的bean定义信息:

2、refresh中invokeBeanFactoryPostProcessors

实例化内部bean(ConfigurationClassPostProcessor)

通过postProcessBeanDefinitionRegistry方法解析配置类

处理配置类AppConifg的注解

@PropertySource的处理会加载MyConfig.properties文件,然后解析其中的键值。

@ComponentScan的处理会构建扫描器,对指定包下所有类进行扫描,符合条件的注册到容器。

此案例此处会把MyService注册到容器。

MyService上有@Service注解,@Service注解中有@Component,所以MyService也会被当做配置类进行处理 。走一遍doProcessConfigurationClass方法的逻辑。

ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor,BeanDefinitionRegistryPostProcessor又继承了BeanFactoryPostProcessor,所以也具有BeanFactoryPostProcessor功能。

postProcessBeanFactory中对符合条件的配置类进行了增强处理。

invokeBeanFactoryPostProcessors结束,容器中有了MyService的bean定义信息、配置文件信息。

bean定义信息:

配置信息:

3、refresh中registerBeanPostProcessors

1、从bean定义信息集合中找到实现了BeanPostProcessor接口的beanDefinition。

org.springframework.context.annotation.internalAutowiredAnnotationProcessor

org.springframework.context.annotation.internalCommonAnnotationProcessor

这两个beanDefinition是最初构造AnnotationConfigApplicationContext时注册到容器的。

2、实例化上述两个后置处理器,然后注册到容器

实例化:

注册:

registerBeanPostProcessors结束,容器中多了两个单例对象,两个后置处理器。

单例:

后置处理器:

4、refresh中finishBeanFactoryInitialization

接下来主要看MyService的实例化过程。

preInstantiateSingletons方法会实例化容器中的单例。

得到MyService的引用后,后置处理器处理。

AutowireAnnotationBeanPostProcessor处理,找到MyService上@Value注解的属性。解析出来后添加到beanDefinition中。

开始给属性赋值

至此关于@Value的解析注入就结束了。

三、小结

1、读取解析配置文件信息,加载到容器待用。

2、实例化过程中,通过后置处理器解析@Value。

3、同样通过后置处理器,找到对应的值,赋值给对应属性。

相关推荐
Volunteer Technology11 小时前
SpringAI Chat Client (四)
人工智能·spring
ShiJiuD66688899911 小时前
springboot基础篇
java·spring boot·spring
敲敲千反田12 小时前
Spring AI
java·人工智能·spring
拽着尾巴的鱼儿12 小时前
spring 动态代理
java·后端·spring
云烟成雨TD13 小时前
Spring AI Alibaba 1.x 系列【52】Interrupts 中断机制:案例演示
java·人工智能·spring
云烟成雨TD13 小时前
Spring AI Alibaba 1.x 系列【51】Graph 整体运行全流程
java·人工智能·spring
_waylau15 小时前
“Java+AI全栈工程师”问答02:Spring Boot 自动配置原理
java·开发语言·spring boot·后端·spring
Ting-yu15 小时前
SpringCloud快速入门(4)---- nacos安装与使用
java·spring·spring cloud
霸道流氓气质15 小时前
Spring AI ChatMemory 对话记忆配置JDBC方式到Mysql数据库实战示例与原理讲解
数据库·人工智能·spring
Java面试题总结15 小时前
我删掉了项目里 80% 的 try-catch,系统反而更稳了
spring