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

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

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;


@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;


@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;


@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;


@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;



//@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注解,重新执行:


针对这三个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;


//@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注入组件了:

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

使用run.getBeanNamesForType可以拿到Fruit类相关的全部组件bean:

如果Fruit的Controller下要自动注入Fruit相关的组件,springboot会提示:


所以这时不能仅使用@Autowired,还需要使用@Qualified(value=“myfruit”)来指定这个组件



postman调用结果如下:

可见,即便是@Qualifier指定的bean是myfruit或者lizhi_fruit,不会抛错,但是springboot拿到的只会是配置绑定的fruit组件。

2.3 上面演示了在实体类Fruit上,增加@Component、@ConfigurationProperties(prefix = “new-fruit”),如果实体类上只有@ConfigurationProperties(prefix = “new-fruit”),那么可以通过在配置类上增加@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;


//@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结果还是配置绑定的:

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5707359.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存