spring boot 三:5.底层注解@ConfigurationProperties配置绑定

spring boot 三:5.底层注解@ConfigurationProperties配置绑定

1 前言:配置绑定

使用java读取properties文件中的内容,并且把它封装到JavaBean中:

在domain下新建一个组件getProperties:
在这里插入图片描述

package com.xiaoxu.domain;

import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

/**
 * @author xiaoxu
 * @date 2022-01-11
 * Ymybatis:com.xiaoxu.domain.getProperties
 */
@Component
public class getProperties {
    public void getSrcProperties() throws IOException {
        Properties p=new Properties();
        p.load(new FileInputStream("src/main/resources/jdbc.properties"));
        Enumeration<?> enumeration = p.propertyNames();
        System.out.println("配置文件名字:"+enumeration);
        while(enumeration.hasMoreElements()){
            String key = (String)enumeration.nextElement();
            String value = p.getProperty(key);
            System.out.println("key:"+key+";"+"value:"+value);
            //封装到JavaBean中
        }
    }
}

在这里插入图片描述
在这里插入图片描述
然后主程序类中调用该方法:

package com.xiaoxu;

import com.xiaoxu.domain.User;
import com.xiaoxu.domain.getProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.io.IOException;

/**
 * @author xiaoxu
 * @date 2022-01-07
 * Ymybatis:com.xiaoxu.MainApplication
 */
@SpringBootApplication(scanBasePackages = {"com.xiaoxu"})
//@EnableAutoConfiguration
//@ComponentScan
//@SpringBootConfiguration
public class MainApplication {
    public static void main(String[] args) throws IOException {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        System.out.println("*******开始*********");
        getProperties bean1 = run.getBean(getProperties.class);
        bean1.getSrcProperties();
        System.out.println("*******结束*********");
    }
}

结果如下:

*******开始*********
配置文件名字:java.util.Hashtable$Enumerator@4912d525
key:url;value:jdbc:mysql://localhost:3306/xiaoxu?useUnicode=true&characterEncoding=utf-8
key:password;value:******
key:driver;value:com.mysql.cj.jdbc.Driver
key:username;value:root
*******结束*********

但是,上述方式读取配置文件中,含有中文时,是会出现乱码的,比如:

package com.xiaoxu.domain;

import org.springframework.stereotype.Component;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;

/**
 * @author xiaoxu
 * @date 2022-01-11
 * Ymybatis:com.xiaoxu.domain.getProperties
 */
@Component
public class getProperties {
    public void getSrcProperties() throws IOException {
        Properties p=new Properties();
        p.load(new FileInputStream("src/main/resources/ts.properties"));
        Enumeration<?> enumeration = p.propertyNames();
        System.out.println("配置文件名字:"+enumeration);
        while(enumeration.hasMoreElements()){
            String key = (String)enumeration.nextElement();
            String value = p.getProperty(key);
            System.out.println("key:"+key+";"+"value:"+value);
            //封装到JavaBean中
        }
    }
}

在这里插入图片描述
执行springboot的MainApplication主程序类,读取数据如下:
在这里插入图片描述
使用InputStreamReader增加properties文件读取的encoding:

package com.xiaoxu.domain;

import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.Properties;

/**
 * @author xiaoxu
 * @date 2022-01-11
 * Ymybatis:com.xiaoxu.domain.getProperties
 */
@Component
public class getProperties {
    public void getSrcProperties() throws IOException {
        Properties p=new Properties();
        InputStream resourceAsStream = Object.class.getResourceAsStream("/ts.properties");
        p.load(new InputStreamReader(resourceAsStream,"utf-8"));
        Enumeration<?> enumeration = p.propertyNames();
        System.out.println("配置文件名字:"+enumeration);
        while(enumeration.hasMoreElements()){
            String key = (String)enumeration.nextElement();
            String value = p.getProperty(key);
            System.out.println("key:"+key+";"+"value:"+value);
            //封装到JavaBean中
        }
    }
}

重新执行springboot主程序类:
在这里插入图片描述
2 @ConfigurationProperties配置绑定

2.1 对于实体类Fruit,使用配置绑定:@ConfigurationProperties(prefix = “new-fruit”),就会默认读取application.yml配置文件中,以new-fruit开头的,自动装配为bean:

package com.xiaoxu.domain;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.Date;

/**
 * @author xiaoxu
 * @date 2022-01-07
 * Ymybatis:com.xiaoxu.domain.Fruit
 */

//@Component
@ConfigurationProperties(prefix = "new-fruit")
public class Fruit {
    /**
     * 水果名称
     */
    private String fname;
    /**
     * 水果价格
     */
    private BigDecimal price;
    /**
     * 水果数目
     */
    private long count;

    /**
     * 水果过期时间
     */
    private Date dropDate;

    public Fruit() {
    }

    public Fruit(String fname, BigDecimal price, long count, Date dropDate) {
        this.fname = fname;
        this.price = price;
        this.count = count;
        this.dropDate = dropDate;
    }

    public Date getDropDate() {
        return dropDate;
    }

    public void setDropDate(Date dropDate) {
        this.dropDate = dropDate;
    }

    public String getFname() {
        return fname;
    }

    public void setFname(String fname) {
        this.fname = fname;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public long getCount() {
        return count;
    }

    public void setCount(long count) {
        this.count = count;
    }

    @Override
    public String toString() {
        return "水果{" +
                "fname='" + fname + '\'' +
                ", price=" + price +
                ", count=" + count +
                ", dropDate=" + dropDate +
                '}';
    }
}

在这里插入图片描述
注意,如果这里不给Fruit类加上@Component(或者@Service、@Repository、@Controller注解),那么即使使用了配置绑定,这个组件(bean)也没有注册到springboot中,无法通过run.getBeanNamesForType(Fruit.class)来获得该fruit组件(@Component,默认的组件名称,是类的小驼峰写法),如下:
在这里插入图片描述
为实体类Fruit增加@Component注解,重新执行主程序类:
在这里插入图片描述

ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

使用run.getBeanNamesForType可以拿到Fruit类相关的全部组件bean:
在这里插入图片描述
在这里插入图片描述
针对这三个Fruit相关的组件,另外两个如下:

package com.xiaoxu.config;

import com.xiaoxu.domain.Fruit;
import com.xiaoxu.domain.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.*;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author xiaoxu
 * @date 2021-12-27
 * Ymybatis:com.xiaoxu.config.MyConfig
 */
//@Import({User.class})
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(name = "my")
@ImportResource(value = "classpath:beans.xml",locations = "classpath:beans.xml")
public class MyConfig {
//    @Bean(name = "fruit")
    @Bean(name = "myfruit",value = "myfruit")
//    @ConditionalOnBean(name = "myuser")
    public Fruit getFruit() throws ParseException {
        Fruit fruit = new Fruit();
        fruit.setFname("桃子");
        fruit.setPrice(new BigDecimal("12.5"));
        fruit.setCount(120);
        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(s.format(new Date()));
        String d = s.format(new Date());
        System.out.println(s.parse(d));
        fruit.setDropDate(s.parse(d));
        return fruit;
    }

    @Bean
    public User getUser(){
        User u=new User();
        u.setName("xiaoxu");
        u.setAge((byte)29);
        u.setMoney(new BigDecimal("10"));
        u.setId(1234);
        return u;
    }
}

这是config下的MyConfig配置类,因为使用了@ImportResource(value = “classpath:beans.xml”,locations = “classpath:beans.xml”)注解,所以也导入了beans.xml里面的lizhi_fruit组件:
在这里插入图片描述
2.2 针对配置绑定、配置类@Bean、以及@ImportResource(value = “classpath:beans.xml”,locations = “classpath:beans.xml”)这几种方式为springboot导入组件bean,就不能单独使用@Autowired注入组件了:

如果Fruit的Controller下要自动注入Fruit相关的组件,springboot会提示:
在这里插入图片描述
在这里插入图片描述
所以这时不能仅使用@Autowired,还需要使用@Qualifier(value=“myfruit”)来指定这个组件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
postman调用结果如下:
在这里插入图片描述
可见,即便是@Qualifier指定的bean是myfruit或者lizhi_fruit,不会抛错,但是springboot拿到的只会是配置绑定的fruit组件。

2.3 上面演示了在实体类Fruit上,增加@Component、@ConfigurationProperties(prefix = “new-fruit”),如果实体类上只有@ConfigurationProperties(prefix = “new-fruit”),那么可以通过在配置类上(使用了@Configuration注解的类为配置类)增加@EnableConfigurationProperties(Fruit.class)来实现配置绑定:

package com.xiaoxu.config;

import com.xiaoxu.domain.Fruit;
import com.xiaoxu.domain.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.*;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author xiaoxu
 * @date 2021-12-27
 * Ymybatis:com.xiaoxu.config.MyConfig
 */
//@Import({User.class})
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(name = "my")
@ImportResource(value = "classpath:beans.xml",locations = "classpath:beans.xml")
@EnableConfigurationProperties(Fruit.class)
public class MyConfig {
//    @Bean(name = "fruit")
    @Bean(name = "myfruit",value = "myfruit")
//    @ConditionalOnBean(name = "myuser")
    public Fruit getFruit() throws ParseException {
        Fruit fruit = new Fruit();
        fruit.setFname("桃子");
        fruit.setPrice(new BigDecimal("12.5"));
        fruit.setCount(120);
        SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(s.format(new Date()));
        String d = s.format(new Date());
        System.out.println(s.parse(d));
        fruit.setDropDate(s.parse(d));
        return fruit;
    }

    @Bean
    public User getUser(){
        User u=new User();
        u.setName("xiaoxu");
        u.setAge((byte)29);
        u.setMoney(new BigDecimal("10"));
        u.setId(1234);
        return u;
    }
}

在这里插入图片描述
然后,该组件名称会改为如下(prefix+"-"+全限定Fruit类名):
在这里插入图片描述
然后重新调用FruitController结果还是配置绑定的:
在这里插入图片描述
在这里插入图片描述
注意:如果去掉Fruit实体类上方的@ConfigurationProperties(prefix = “new-fruit”)配置绑定注解,也需要去掉配置类上的@EnableConfigurationProperties(Fruit.class),否则springboot抛错,配置类找不到配置绑定:

java.lang.IllegalStateException: No ConfigurationProperties annotation found on  'com.xiaoxu.domain.Fruit'.

故而,一般是实体类@Component和@ConfigurationProperties(prefix = “new-fruit”)一起使用;或者是实体类使用@ConfigurationProperties(prefix = “new-fruit”),配置类使用@EnableConfigurationProperties(Fruit.class)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,可以使用@ConfigurationProperties注解来将配置文件中的属性值与Java对象进行绑定。这样可以方便地管理应用程序的配置属性。 下面是使用@ConfigurationProperties注解的步骤: 1. 创建一个Java类,并在类上添加@ConfigurationProperties注解。该注解的value属性指定了配置文件中的前缀,prefix属性指定了配置文件中的属性前缀。例如,如果配置文件中的属性为myconfig.name,那么可以将value属性设置为"myconfig"。 ```java @ConfigurationProperties(prefix = "myconfig") public class MyConfigProperties { private String name; // getter和setter方法 } ``` 2. 在配置文件(application.properties或application.yml)中定义属性值。例如,在application.properties中添加以下内容: ``` myconfig.name=bj ``` 3. 在Spring Boot应用程序的主类中,使用@EnableConfigurationProperties注解来启用@ConfigurationProperties注解。将@ConfigurationProperties注解的类作为参数传递给@EnableConfigurationProperties注解。 ```java @SpringBootApplication @EnableConfigurationProperties(MyConfigProperties.class) public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } } ``` 现在,可以在其他组件中注入使用@ConfigurationProperties注解的类,并使用其中的属性值。例如,在一个Service类中注入MyConfigProperties类: ```java @Service public class MyService { private final MyConfigProperties configProperties; public MyService(MyConfigProperties configProperties) { this.configProperties = configProperties; } public void printName() { System.out.println("Name: " + configProperties.getName()); } } ``` 这样,就可以在应用程序中使用@ConfigurationProperties注解来管理配置属性了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值