zoukankan      html  css  js  c++  java
  • SpringBoot学习(五)

    获取全局配置文件中自定义配置的值,常用有两种方式:

    自己定义一个配置文件test.properties

    my.name=xuhaixing
    my.age=25
    my.sex=man

     一、使用@Value("${}")注解进行某个属性的注入

    @Configuration  //证明这是一个配置类
    @PropertySource(value = {"classpath:test.properties"}, ignoreResourceNotFound = true)//可以放多个,{}里面用,分开
    public class User {
     
        //可以不用set方法,直接就能注入,属于注入
        @Value("${my.name}")
        private String name;
     
        @Value("${my.age}")
        private int age;
     
        @Value("${my.sex}")
        private String sex;
     
     
        public String getName() {
            return name;
        }
     
        public int getAge() {
            return age;
        }
     
        public String getSex() {
            return sex;
        }
     
    }

     注意:使用@value注解所在的类必须是一个IOC容器中的对象,即使用@Configuration、@Component等注解注入到容器的对象。

     其中@PropertySource指明要加载的配置文件,如果没有用该注解指明,默认读取的springboot的全局配置文件,即:application.properties或application.yml

    可以在controller中把user类注入,然后测试一下:

    @RestController
    public class HelloController {
     
        @Autowired
        private User user;
     
        @RequestMapping(value = "/getUser")
        public String getUser() {
            return user.getName() + " " + user.getSex() + " " + user.getAge();
        }
    }

    注意:省略了springboot的pom文件以及启动类

    二、使用@ConfigurationProperties注解进行对象属性的全量注入

    @Configuration
    @PropertySource(value = "classpath:test.properties")
    @ConfigurationProperties(prefix = "my")  //需要有set方法,prefix指明该对象中所有属性的前缀,对应文件中的属性名
    public class UserPrefix {
        private String name;
        private int age;
        private String sex;
     
     
        public void setName(String name) {
            this.name = name;
        }
     
        public void setAge(int age) {
            this.age = age;
        }
     
        public void setSex(String sex) {
            this.sex = sex;
        }
     
        public String getName() {
            return name;
        }
     
        public int getAge() {
            return age;
        }
     
        public String getSex() {
            return sex;
        }
    }

    然后注入到controller中,测试

    @RestController
    @EnableConfigurationProperties({UserPrefix.class})  //激活配置,测试了一下,也可以没有
    public class HelloPrefixController {
     
        @Autowired
        private UserPrefix userPrefix;
     
        @RequestMapping(value = "/getUserPrefix")
        public String getUserPrefix() {
            return userPrefix.getName() + " " + userPrefix.getSex() + " " + userPrefix.getAge();
        }
     
    }

    注意:两种让@ConfigurationProperties生效的方法:

    1、在这里@ConfigurationProperties所注解的类,添加了@Configuration注解,表示该类UserPrefix会注入到IOC容器中作为bean,所以@ConfigurationProperties注解就可以自动生效,自动全量注入该对象的自定义属性。其实把@Configuration替换成@Component等任何一个可以实现注入IOC容器的注解都可以使@ConfigurationProperties生效;

    2、如果@ConfigurationProperties所注解的类没有添加注解注入到IOC容器中,则必须在使用的地方添加@EnableConfigurationProperties注解并指明需要注入到容器的类,来注入到容器中,从而使@ConfigurationProperties生效;

    结论:这里用了@Configuration注解,所以可以去掉@EnableConfigurationProperties({UserPrefix.class}) ,测试没问题。

     三、@ConfigurationProperties 与 @Value 有什么区别呢?

     

    @ ConfigurationProperties

    @ Value
    功能 批量注入 单个注入
    松散绑定(松散语法) 支持 不支持
    SpEL 不支持 支持
    JSR303数据校验 支持 不支持
    复杂类型封装 支持 不支持

     

    • 批量注入:使用 @ConfigurationProperties 与@Value 发现,
      @ConfigurationProperties 注解一个类或者方法就可以将所有的配置项注入到类中。而@Value 则需要将类中的每个属性注解才能读取配置项。
    • 松散绑定(松散语法):就是配置文件中的属性书写方式。
    person.fullName 与类中同名
    person.full-name 使用 - 替换大写
    person.full_name 使用 _ 替换大写

     @Value 不支持 松散绑定,配置文件名必须和类属性名相同。否则则会报错:

    Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'person.fullNname' in value "${person.fullNname}"
    • SpEL:EL 表达式
    @Value("#{11*2}")
    private Integer age;
    • JSR303数据校验
    @Data
    @Component
    @ConfigurationProperties(prefix = "person")
    @Validated //JSR303数据校验
    public class Person {
        @NotNull //不能为空
        private String name;
        @Email // 必须为Email 格式
        private String fullName;
        private Integer age;
        private List<String> list;
        private Map<String,String> map;
        private Dog dog;
    }
    person:
      name: xiaoming
      full-name: 小明
      age : 11
      list:
        -a -b -c -d
      map: {key1: value1,key2: value2}
      dog:
        name: tom
        age: 3

    此时full-name并不是一个Email 格式内容,启动项目报错:

    Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'person' to com.example.demo.entity.Person failed:
    
        Property: person.fullName
        Value: 小明
        Origin: class path resource [application.yml]:9:14
        Reason: 不是一个合法的电子邮件地址
    • 复杂类型封装: List Map 等。

    @Value 并不支持读取复杂类型的配置项。

    @ConfigurationProperties处理复杂类型的例子如下:

    属性文件如下:

    com.zyd.type3=Springboot - @ConfigurationProperties
    com.zyd.title3=使用@ConfigurationProperties获取配置文件
    #map
    com.zyd.login[username]=zhangdeshuai
    com.zyd.login[password]=zhenshuai
    com.zyd.login[callback]=http://www.flyat.cc
    #list
    com.zyd.urls[0]=http://ztool.cc
    com.zyd.urls[1]=http://ztool.cc/format/js
    com.zyd.urls[2]=http://ztool.cc/str2image
    com.zyd.urls[3]=http://ztool.cc/json2Entity
    com.zyd.urls[4]=http://ztool.cc/ua
    
    @Component
    @ConfigurationProperties(prefix = "com.zyd")
    public class PropertiesConfig {
    
        public String type3;
        public String title3;
        public Map<String, String> login = new HashMap<String, String>();
        public List<String> urls = new ArrayList<>();
    
        public String getType3() {
            return type3;
        }
    
        public void setType3(String type3) {
            this.type3 = type3;
        }
    
        public String getTitle3() {
            try {
                return new String(title3.getBytes("ISO-8859-1"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return title3;
        }
    
        public void setTitle3(String title3) {
            this.title3 = title3;
        }
    
        public Map<String, String> getLogin() {
            return login;
        }
    
        public void setLogin(Map<String, String> login) {
            this.login = login;
        }
    
        public List<String> getUrls() {
            return urls;
        }
    
        public void setUrls(List<String> urls) {
            this.urls = urls;
        }
    
    } 

    启动类:

    @SpringBootApplication
    @RestController
    public class Applaction {
    
        @Autowired
        private PropertiesConfig propertiesConfig;
    
        @RequestMapping("/config")
        public Map<String, Object> configurationProperties() {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("type", propertiesConfig.getType3());
            map.put("title", propertiesConfig.getTitle3());
            map.put("login", propertiesConfig.getLogin());
            map.put("urls", propertiesConfig.getUrls());
            return map;
        }
    
        public static void main(String[] args) throws Exception {
            SpringApplication application = new SpringApplication(Applaction.class);
            application.run(args);
        }
    }

     

    转载:https://blog.csdn.net/u012326462/article/details/80686462

    https://www.jianshu.com/p/7f4fc5c19e4d

    https://blog.csdn.net/thc1987/article/details/78789426

  • 相关阅读:
    容器级虚拟化如何进行资源分配
    容器虚拟化实现的原理
    tensorflow报cudnn错误
    nginx调优
    mysql主从原理及配置
    新安装mysql,如何提升mysql安全性
    LINUX系统软件安装和卸载的常见方法
    如何增加黑客通过ssh入侵的难度--保护ssh的三把锁
    ubuntu-docker入门到放弃(八)创建支持SSH服务的镜像
    ubuntu-docker入门到放弃(七)操作系统
  • 原文地址:https://www.cnblogs.com/cainiao-Shun666/p/11433904.html
Copyright © 2011-2022 走看看