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)。

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
spring-boot-mvc-jpa-data-mysql 这是一个用gradle构建的一个spring boot应用程序, 该程序包含了spring mvc 4,spring data jpa 和 jsp, 主要展示了Controller,RestController 的用法, 以及数据绑定,分页,持久化,控制器返回json或html 数据等, 数据库既可以用mysql,也可以用hsqldb,默认使用hsqldb, 即在没有安装数据库的情况下亦可运行项目进行测试 这里还用了springloaded,spring 的一个热部署项目,虽然不及jrebel强大 但是这里绝对够用,不管你添加了多少方法,或者修改方法名,参数结构,修改注解 等一系列操作都能热加载,只有一个缺点,就是新增Controller不能识别,但是问题不大 只需要预先把Controller创建好就行了,总体体验还行,值得推荐
Direct–路由模式 任何发送到Direct Exchange的消息都会被转发到RouteKey指定的Queue。 这种模式下不需要将Exchange进行任何绑定(binding)操作。 消息传递时需要一个“RouteKey”,可以简单的理解为要发送到的队列名字。 如果vhost中不存在RouteKey中指定的队列名,则该消息会被抛弃。 Fanout–发布/订阅模式 任何发送到Fanout Exchange的消息都会被转发到与该Exchange绑定(Binding)的所有Queue上。 这种模式不需要RouteKey。 这种模式需要提前将Exchange
@ConfigurationProperties注解提示Configuration Annotation Proessor not found in classpath 解决方案 @ConfigurationProperties注解提示Configuration Annotation Proessor not found in classpath 解决方案 菜鸟本人要配置一个七牛云的上传Demo,...
文章目录Spring Boot Test单元测试环境搭建Service层的单元测试Controller层的单元测试Repository层的测试测试环境配置bootstrap-test.yml文件参考源代码 Spring Boot Test单元测试环境搭建 首先我用到了PowerMock和Mockito。所以先加入PowerMock和Mockito的依赖。PowerMock和Mockito的版本使...
@Configuration//声明类是一个java配置类,相当于xml文件 //@PropertySource("classpath:jdbc.properties")//读取资源文件 //@EnableConfigurationProperties(JdbcProperties.class) public class JdbcConfiguration { //第四种配置方式:一段属性只有一个...
@Configuration//标记该类是一个配置类 @ConditionalOnWebApplication//标记该自动配置类只有在 Web应用下才会生效 @EnableConfigurationProperties(SpringDemo.class)//开启自动属性配置 public class HelloServiceAutoConfiguration {... bootcloud的版本选型 Ⅰ.进入springcloud官方页面:https://spring.io/projects/spring-cloud#learn Ⅱ. LEARN->Reference Doc. 选择对应的版本即可
@EnableConfigurationProperties注解通常和@ConfigurationProperties注解一起使用,将标记了@ConfigurationProperties的bean绑定配置文件中的属性并将其注册到IOC容器之中。 首先看下@EnableConfigurationProperties注解的源码 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(EnableCo.
将项目配置文件下的Spring Cloud Config Client配置信息写在 bootstrap.yml或者bootstrap.properties文件中(而不是application.yml或者application.properties) 因为boot...
目录五、springboot中第方组件如何实现自动配置spring-boot-autoconfigure-2.1.9.RELEASE.jarRedisProperties@EnableConfigurationProperties注解@Import 注解简述 五、springboot中第方组件如何实现自动配置 我们知道springboot 只需要引入一个starter就可以完成一个组件的集成,...
原因:@ConfigurationProperties(prefix =“author”)没有指定classpath时,IDEA提示没有找到classpath。 高版本的Spring Boot中@ConfigurationProperties注解去掉了localhost属性,导致发生这个错误,所以建议还是直接从配置文件中读取字段而不是获取对象。