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

目录
  • 读取自定义properties注入到bean
    • springboot启动日志如下
  • springboot bean实例化和属性注入过程
    • springboot版本(2.0.4 RELEASE)
    • Bean的实例化
    • Bean的属性注入

读取自定义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启动日志如下

然后在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()方法

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

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

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

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

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

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

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

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

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

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

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

Bean的属性注入

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

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

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

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

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 在SpringBoot下读取自定义properties配置文件的方法

    SpringBoot工程默认读取application.properties配置文件.如果需要自定义properties文件,如何读取呢? 一.在resource中新建.properties文件 在resource目录下新建一个config文件夹,然后新建一个.properties文件放在该文件夹下.如图remote.properties所示 二.编写配置文件 remote.uploadFilesUrl=/resource/files/ remote.uploadPicUrl=/resource

  • Springboot如何通过自定义工具类获取bean

    目录 Springboot 自定义工具类获取bean 在工具类注入bean的三种方式 1. 需求/目的 2.使用环境 3.方法一:获取ApplicationContext上下文 4.方法二:将工具类的对象也添加为bean 5.方法三:在spring Boot 启动时创建工具类自身的静态对象 Springboot 自定义工具类获取bean /** * Created with IntelliJ IDEA. * * @Auther: zp * @Date: 2021/03/26/13:32 * @D

  • java SpringBoot自定义注解,及自定义解析器实现对象自动注入操作

    # java-SpringBoot自定义参数解析器实现对象自动注入 解析器逻辑流程图表 后台解析注解的解析器 首先,我在java后台编写了一个解析器,代码如下 import com.ruoyi.framework.interceptor.annotation.LoginUser; import com.ruoyi.project.WebMoudle.WebUser.domain.WebUser; import com.ruoyi.project.WebMoudle.WebUser.service

  • Spring boot将配置属性注入到bean类中

    一.@ConfigurationProperties注解的使用 看配置文件,我的是yaml格式的配置: // file application.yml my: servers: - dev.bar.com - foo.bar.com - jiaobuchong.com 下面我要将上面的配置属性注入到一个Java Bean类中,看码: import org.springframework.boot.context.properties.ConfigurationProperties; import

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

    目录 读取自定义properties注入到bean springboot启动日志如下 springboot bean实例化和属性注入过程 springboot版本(2.0.4 RELEASE) Bean的实例化 Bean的属性注入 读取自定义properties注入到bean 在使用springboot项目时,可使用@value的方式直接读取application.properties中的文件,但有时我们需要配置自定义的properties,下面方法将在springboot启动时利用filein

  • springboot如何读取自定义配置项

    我们springboot项目有自己默认的配置文件,一般地由application.yml和bootstrap.yml组成,前者是模块的配置,后者是微服务的配置,后台比前者先被框架加载. 我们有时需要自己定义配置,可能不是简单的字符串,它可能是一个对象,对象里有具体的配置段,它也是application.yml的一部分,你可以把自己的代码添加上,当然你也可以新建全新的文件. 例如,有一个配置由name和version组成,我们在application.yml里可以把它定义成project元素下面的

  • Springboot 读取自定义pro文件注入static静态变量方式

    Springboot 读取pro文件注入static静态变量 mailConfig.properties #服务器 mail.host=smtp.qq.com #端口号 mail.port=587 #邮箱账号 mail.userName=hzy_daybreak_lc@foxmail.com #邮箱授权码 mail.passWord=vxbkycyjkceocbdc #时间延迟 mail.timeout=25000 #发送人 mail.emailForm=hzy_daybreak_lc@foxm

  • springboot实现将自定义日志格式存储到mongodb中

    步骤如下 首先定义封装所需要的日志信息的实体类 public class MyLog { //根据需要定义字段 @Id private String id; private Date ts; private String level; private String msg; private String thread; //属性的get/set方法(略) } 定义操作mongodb的接口 @Repository public interface LogRepository extends Mon

  • SpringBoot读取自定义配置文件方式(properties,yaml)

    目录 一.读取系统配置文件application.yaml 二.读取自定义配置文件properties格式内容 三.读取自定义配置文件yaml格式内容 四.其他扩展内容 一.读取系统配置文件application.yaml 1.application.yaml配置文件中增加一下测试配置 testdata: animal: lastName: 动物 age: 18 boss: true birth: 2022/02/22 maps: {key1:value1,key2:value2} list:

  • springboot读取自定义配置文件节点的方法

    今天和大家分享的是自定义配置信息的读取:近期有写博客这样的计划,分别交叉来写springboot方面和springcloud方面的文章,因为springboot预计的篇章很多,这样cloud的文章就需要等到很后面才能写了:分享这两种文章的原因主要是为了方便自己查找资料使用和对将要使用的朋友起到便捷作用: •@Value标记读取(默认可直接读取application.yml的节点) •实体映射application.yml的节点 •实体映射自定义配置文件的节点 •实体映射多层级节点的值 @Valu

  • SpringBoot读取properties或者application.yml配置文件中的数据

    读取application文件 在application.yml或者properties文件中添加: user.address=china user.company=demo user.name=让我康康 1.使用@Value注解读取 直接 代码如下: package im.homeapi.controller; import org.springframework.beans.factory.annotation.Value; import org.omg.CORBA.PUBLIC_MEMBE

  • SpringBoot不读取bootstrap.yml/properties文件问题

    目录 今天写创建了一个SpringBoot项目,配置文件从其他项目拷贝了一份bootstrap.yml 之前一直用的application.yml 心想:application.yml 优先级没有bootstrap.yml 高,bootstrap配置文件肯定没问题 项目一跑来,发现配置文件里面的内容没读取到. 之后通过各种查资料,才明白了application.yml 和bootstrap.yml 的区别,不仅仅是优先级的问题. 先说我的问题是什么原因吧: SpringBoot 项目中如果没有依

  • springboot application.properties 文件注入数组方式

    目录 application.properties 文件注入数组 在application.properties中注入value,list和map 配置文件 注解 数据注入 application.properties 文件注入数组 1.application.properties ips=192.168.0.105,192.168.0.106,0:0:0:0:0:0:0:1 2.代码 @Value("#{'${ips}'.split(',')}") private List<S

随机推荐