springboot如何读取自定义properties并注入到bean中

作者:ming199481 时间:2022-12-16 22:22:09 

读取自定义properties注入到bean

在使用springboot项目时,可使用@value的方式直接读取application.properties中的文件,但有时我们需要配置自定义的properties,下面方法将在springboot启动时利用fileinputstream读取properties文件中的内容,并注入到bean中,@Configuration注解会在springboot启动时执行一次,代码如下:


package com.shanqis.parking.properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
* 读取resource下的.properties文件,将文件中的内容封装到map中,注入到bean中方便依赖注入
*
* @author Administrator
*/
@Configuration
public class PropertiesClassLoader {
   private Logger logger = LoggerFactory.getLogger(PropertiesClassLoader.class);
   private Map<String, Object> versionProperties = new HashMap<>(16);
   private void init(String name) {
       try {
           Properties properties = new Properties();
           InputStream in = PropertiesClassLoader.class.getClassLoader().getResourceAsStream(name + ".properties");
           properties.load(in);
           logger.info("加载{}.properties参数", name);
           for (String keyName : properties.stringPropertyNames()) {
               String value = properties.getProperty(keyName);
               if ("version".equals(name)) {
                   versionProperties.put(keyName, value);
               }
               logger.info("{}.properties---------key:{},value:{}", name, keyName, value);
           }
           logger.info("{}.properties参数加载完毕", name);
       } catch (IOException ignored) {
       }
   }

@Bean(name = "versionProperties")
   public Map<String, Object> commonMap() {
       init("version");
       return versionProperties;
   }
}

springboot启动日志如下

springboot如何读取自定义properties并注入到bean中

然后在controller层或者service层等可以这样使用


/**
* 读取common.properties文件
*/
@Autowired @Qualifier("commonMap")
protected Map<String, String> commonMap;

springboot bean实例化和属性注入过程

springboot版本(2.0.4 RELEASE)

大致描述springboot中bean的实例化和属性注入过程流程

1) 在某一时刻Spring调用了Bean工厂的getBean(beanName)方法。beanName可能是simpleController,或者simpleService,simpleDao,顺序没关系(因为后面会有依赖关系的处理)。我们假设simpleController吧

2)getBean方法首先会调用Bean工厂中定义的getSingleton(beanName)方法,来判断是否存在该名字的bean单例,如果存在则返回,方法调用结束(spring默认是单例,这样可以提高效率)

3) 否则,Spring会检查是否存在父工厂,如果有则返回,方法调用结束

4) 否则,Spring会检查bean定义(BeanDefinition实例,用来描述Bean结果,component-scan扫描后,就是将beanDefinition实例放入Bean工厂,此时还没有被实例化)是否有依赖关系,如果有,执行1)步,获取依赖的bean实例

5) 否则,Spring会尝试创建这个bean实例,创建实例前,Spring会检查调用的构造器,并实例化该Bean,(通过Constructor.newInstance(args)进行实例化)

6) 实例化完成后,Spring会调用Bean工厂的populateBean方法来填充bean实例的属性,也就是自动装配。populateBean方法便是调用了BeanPostProcessor实例来完成属性元素的自动装配工作

7)在元素装配过程中,Spring会检查被装配的属性是否存在自动装配的其他属性,然后递归调用getBean方法,知道所有@Autowired的元素都被装配完成。如在装配simpleController中的simpleService属性时,发现SimpleServiceImpl实例中存在@Autowired属性simpleDao,然后调用getBean(simpleDao)方法,同样会执行1)----7)整个过程。所有可以看成一个递归过程。

8)装配完成后,Bean工厂会将所有的bean实例都添加到工厂中来。

Bean的实例化

1. 进入SpringApplication类中refreshContext()方法

springboot如何读取自定义properties并注入到bean中

2. 进入AbstractApplicationContext类中refresh()方法,找到this.finishBeanFactoryInitialization()方法,这个方法就是完成beanFactory的实例化

springboot如何读取自定义properties并注入到bean中

3. 进入AbstractApplicationContext类中finishBeanFactoryInitialization()方法,找到preInstantiateSingletons()

springboot如何读取自定义properties并注入到bean中

4. 进入DefaultListableBeanFactory类中preInstantiateSingletons()方法,找到getBean()方法

springboot如何读取自定义properties并注入到bean中

5. 进入AbstractBeanFactory类中getBean()方法,找到doGetBean()方法

springboot如何读取自定义properties并注入到bean中

6. 在AbstractBeanFactory类中doGetBean方法中,找到createBean()方法

springboot如何读取自定义properties并注入到bean中

7. 进入AbstractAutowireCapableBeanFactory类中createBean方法中,找到doCreateBean()方法

springboot如何读取自定义properties并注入到bean中

8. 在AbstractAutowireCapableBeanFactory类中doCreateBean()方法中,找到createBeanInstance()方法,看名字就知道是实例化bean的

springboot如何读取自定义properties并注入到bean中

9. 在AbstractAutowireCapableBeanFactory类createBeanInstance()方法中,找到instantiateBean()方法

springboot如何读取自定义properties并注入到bean中

10. 在AbstractAutowireCapableBeanFactory类instantiateBean()方法中,找到instantiate()方法

springboot如何读取自定义properties并注入到bean中

11. 在SimpleInstantiationStrategy类instantiate()方法中,找到instantiateClass()方法

springboot如何读取自定义properties并注入到bean中

12. 在BeanUtils类instantiateClass()方法中,可知bean的实例化是通过Constructor.newInstance()进行实例化

springboot如何读取自定义properties并注入到bean中

Bean的属性注入

1. 在AbstractAutowireCapableBeanFactory类doCreateBean()方法中,找到populateBean()方法,从名字可知是用来填充bean的

springboot如何读取自定义properties并注入到bean中

2. 在AbstractAutowireCapableBeanFactory类中populateBean()方法,找到postProcessPropertyValues()方法

springboot如何读取自定义properties并注入到bean中

3. 进入AutowiredAnnotationBeanPostProcessor类中postProcessPropertyValues()方法中,找到findAutowiringMetadata()方法,在这个方法中,如果属性中含有@Autowired注解则会递归getBean()。没有然后进入inject()方法中

springboot如何读取自定义properties并注入到bean中

4. 进入AutowiredAnnotationBeanPostProcessor类inject方法中,找到resolveDependency()方法,通过这个方法获取对应字段的值

springboot如何读取自定义properties并注入到bean中

5. 进入AutowiredAnnotationBeanPostProcessor类inject方法中,找到field.set(bean, value)方法,通过反射将值设置到属性中

springboot如何读取自定义properties并注入到bean中

来源:https://blog.csdn.net/ming199481/article/details/80500444

标签:springboot,properties,bean
0
投稿

猜你喜欢

  • 使用java实现http多线程断点下载文件(一)

    2023-11-23 15:45:51
  • C#微信开发之获取接口调用凭据

    2023-10-28 07:57:54
  • Android定时器实现定时执行、重复执行、定时重复执行、定次数执行的多种方式

    2022-06-30 02:07:26
  • Javaweb获取表单数据的多种方式

    2022-12-25 18:13:41
  • Android自定义控件仿QQ编辑和选取圆形头像

    2022-11-10 09:40:37
  • 解析Java的JNI编程中的对象引用与内存泄漏问题

    2023-03-19 20:59:28
  • 从java源码分析线程池(池化技术)的实现原理

    2021-12-24 00:01:24
  • Java线程生命周期及转换过程

    2023-12-27 21:22:15
  • Springboot整合Shiro的代码实例

    2021-09-03 04:16:52
  • C# CancellationToken和CancellationTokenSource的用法详解

    2023-05-26 19:39:41
  • SpringBoot实现任意位置获取HttpServletRequest对象

    2023-07-07 10:26:40
  • 详解Spring Boot + Mybatis 实现动态数据源

    2023-06-08 13:53:18
  • C#中的静态成员、静态方法、静态类介绍

    2022-04-25 20:06:51
  • 详解DES加密算法的原理与Java实现

    2021-06-22 06:56:19
  • Log4j.properties配置及其使用

    2023-05-14 21:06:18
  • java实现学籍管理系统

    2023-04-03 00:32:19
  • python调用java的jar包方法

    2023-06-23 21:54:24
  • c#定时器使用示例详解

    2022-01-09 03:31:05
  • SpringBoot web静态资源配置详解

    2023-09-24 14:13:26
  • C#之CLR内存原理初探

    2023-02-16 00:58:09
  • asp之家 软件编程 m.aspxhome.com