SpringBoot2学习笔记——注解、工具、yaml、配置文件代码提示

@Configuration、@Bean

SpringBoot 使用完全注解开发模式,使用配置类代替 xml 配置文件。

  • 注解@Configuration声明配置类,属性proxyBeanMethods声明配置类内的方法是否为代理 Bean 方法。
    • proxyBeanMethods=true:是代理 Bean 方法,开启 Full 模式。任何位置调用配置类内的方法,返回一个组件时,都会到 IOC 容器中去查找组件,因此返回的都是同一个组件对象。保证每个 @Bean 方法无论被调用多少次,返回的组件都是单实例的。
    • proxyBeanMethods=false:不是代理 Bean 方法,开启 Lite 模式。任何位置调用配置类内的方法,返回一个组件时,都会新创建一个组件。因此 @Bean 方法被调用几次,就会新创建几次组件。
    • 配置类内组件之间无依赖关系时,使用 Lite (false) 模式加速容器启动,减少判断;配置类内组件之间有依赖关系时,使用 Full (true) 模式。
    • 注意:proxyBeanMethods属性,只会影响本配置类内的方法返回的实例,对本配置类外的组件实例,没有影响。如使用 @Component 创建的实例,始终是单例的,不会因为属性值设置为 false,就变为多实例。
    • 配置类内只有一个有参构造器时,有参构造器所有参数的值都会从 IOC 容器中获取,并自动注入到参数中。
  • 注解@Bean向 IOC 容器中添加组件,函数名为 bean 标签的 id,返回值类型为 bean 标签的 class,返回值为保存到 IOC 容器的实例。可以通过 value 属性,设置 id 值。
    • 向 @Bean 注解标注的方法中传入参数时,SpringBoot (Spring) 会在 IOC 容器中查询该组件是否存在,若存在,则会 autowire 到形参中,若不存在,则报错。
      在这里插入图片描述

SpringBootConfig.java

/**
 * 配置类,代替xml配置文件,完全注解开发模式
 */
@Configuration(proxyBeanMethods = true)//声明该类为配置类
public class SpringBootConfig {
    @Bean//声明该方法向IOC容器中添加bean对象,
    // 函数名user01为bean标签的id,返回值类型User为bean标签的class,返回值为保存到IOC容器的实例
    public User user01(){
        User user = new User("mcc",onePlus6T());
        return user;
    }

    @Bean("onePlus6T")
    public Phone onePlus6T(){
        Phone onePlus6T = new Phone("onePlus6T");
        return onePlus6T;
    }
}

MainApplication.java

/**
 * 主程序类
 * 使用注解:@SpringBootApplication,声明主类
 */
@SpringBootApplication()//声明该类为主类
public class MainApplication {
    public static void main(String[] args) {
        //ConfigurableApplicationContext:IOC容器类,可以查询和获取容器内的所有对象
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        //在IOC容器中获取id=user01的对象
        User user01 = run.getBean("user01", User.class);
        System.out.println(user01);//User{username='mcc', phone=Phone{type='onePlus6T'}}
        //获取容器中的全部组件名
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) {
            System.out.println(name);
        }
    }
}

User.java Phone.java

public class User {
    private String username;
    private Phone phone;
}

public class Phone {
    private String type;
}

下面这种方式创建的 user02 对象是单例的,即使 ProxyBeanMethod=false。

@Component("user02")
public class User {
    @Value("mcc")
    private String username;
    @Autowired
    private Phone phone;
}

其他注解

在 Spring、springMVC 中使用的注解,如@Component、@Controller、@Service、@Repository、@ComponentScan等,在 SpringBoot 中也可以使用,且用法相同。

@Import

@Import注解使用在任一配置类注解或组件注解上,使用被引入对象的无参构造器创建对象,并引入。引入的组件的默认组件名是类的全类名。

//1
@Import(Phone.class)//引入失败,没有使用在配置类注解或组件注解上
public class User {
    private String username;
    private Phone phone;
}

//2
@Import(Phone.class)//引入成功,使用在组件注解上
@Component
public class User {
    private String username;
    private Phone phone;
}

//3
@Import(Phone.class)//引入成功,使用在配置类注解上
@Configuration(proxyBeanMethods=true)//声明该类为配置类
public class SpringBootConfig {
    @Bean//声明该方法向IOC容器中添加bean对象,
    // 函数名user01为bean标签的id,返回值类型User为bean标签的class,返回值为保存到IOC容器的实例
    public User user01(){
        User user = new User("mcc", onePlus6T());
        return user;
    }

    @Bean("onePlus6T")
    public Phone onePlus6T(){
        Phone onePlus6T = new Phone("onePlus6T");
        return onePlus6T;
    }
}

MainApplication.java 中进行测试

String[] names = run.getBeanNamesForType(Phone.class);
for (String name : names) {
    System.out.println(name);
    //com.mcc.springboot.bean.Phone => @Import引入的组件,id值(名称)默认为全类名
    //onePlus6T => 自己添加的组件
}

@Conditional

@Conditional条件装配,当满足一定的条件时,才会进行组件装配。
在这里插入图片描述
@ConditionalOnBean、@ConditionalOnMissingBean为例:

  • @ConditionalOnBean(value={Xxx.class}, name=""):当 IOC 容器中有 class=Xxx,id="" 的组件时,才注册该方法返回的组件。可以用在类上、方法上,用在类上表示满足条件时,整个类内的组件才可以被注册。
  • @ConditionalOnMissingBean(value={Xxx.class}, name=""):当 IOC 容器中没有满足条件的组件时,才注册下面方法所返回的组件。同样可以用在类上、方法上。

SpringBootConfig.java

@Configuration(proxyBeanMethods=true)//声明该类为配置类
public class SpringBootConfig {
	// @Bean("onePlus6T")//没有注册onePlus6T组件
    public Phone onePlus6T(){
        Phone onePlus6T = new Phone("onePlus6T");
        return onePlus6T;
    }
    
    @ConditionalOnBean(value={Phone.class}, name="onePlus6T")//当IOC容器中有class=phone,id=onePlus6T的组件时,才注册user01组件
    @Bean//声明该方法向IOC容器中添加bean对象,
    // 函数名user01为bean标签的id,返回值类型User为bean标签的class,返回值为保存到IOC容器的实例
    public User user01(){
        User user = new User("mcc", onePlus6T());
        return user;
    }
}

MainApplication.java

/**
 * 主程序类
 * 使用注解:@SpringBootApplication,声明主类
 */
@SpringBootApplication(scanBasePackages="com.mcc.springboot")//声明该类为主类
public class MainApplication {
    public static void main(String[] args) {
        //ConfigurableApplicationContext:IOC容器类,可以查询和获取容器内的所有对象
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        boolean user01 = run.containsBean("user01");
        /*
        由于没有注册onePlus6T组件,因此user01组件也不能被注册,所以返回false;
        将onePlus6T方法的@Bean添加上,则返回true;
        将user01的注解改为:@ConditionalOnMissingBean,则返回true.
		*/
        System.out.println(user01);//false
    }
}

@ImportResource

@ImportResource导入 xml 配置文件中的 bean 组件。使用位置为任一配置类、任一组件注解上。

在很多情况下,工程不是完全注解开发模式,使用的仍然是 xml 配置文件方式。在这种情况下,有两种办法:
(1)手动将配置文件中的 bean 标签转换为配置类中的方法,但是比较麻烦。
(2)使用@ImportResource注解导入配置文件中的 bean 组件。

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user02" class="com.mcc.springboot.bean.User">
        <property name="username" value="lcc"/>
        <property name="phone">
            <null/>
        </property>
    </bean>

</beans>

SpringBootConfig.java

/**
 * 配置类,代替xml配置文件,完全注解开发模式
 */
@Configuration(proxyBeanMethods=true)//声明该类为配置类
@ImportResource("classpath:bean.xml")//引入bean.xml中的bean组件
public class SpringBootConfig {
    
}

MainApplication.java

/**
 * 主程序类
 * 使用注解:@SpringBootApplication,声明主类
 */
@SpringBootApplication(scanBasePackages="com.mcc.springboot")//声明该类为主类
public class MainApplication {
    public static void main(String[] args) {
        //ConfigurableApplicationContext:IOC容器类,可以查询和获取容器内的所有对象
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        if(run.containsBean("user02")){
            User user02 = run.getBean("user02", User.class);
            System.out.println(user02);//User{username='lcc', phone=null}
        }
    }
}

配置绑定

读取 application.properties 中的配置,并注入到 JavaBean 中。

@Component + @ConfigurationProperties

@Component:向容器中添加组件,id 默认为类名首字母小写。
@ConfigurationProperties(prefix=""):为容器中的组件绑定 application.properties 中的属性。注意,若组件还没有添加到容器中,则该注解无效。

prefix属性:application.properties 中,以 prefix 开头的 key 的值,赋值给组件的属性。如,a.b.c=E,prefix=a.b,则组件中名称为 c 的属性被赋值为 E。注意:prefix 中不能用驼峰写法。

application.properties

server.servlet.context-path=/helloworld

bean.car.brand=BT-t77
bean.car.price=100000

Car.java

@Component
@ConfigurationProperties(prefix = "bean.car")
public class Car {
    private String brand;
    private double price;
}

MainApplication.java

@SpringBootApplication(scanBasePackages="com.mcc.springboot")//声明该类为主类
public class MainApplication {
    public static void main(String[] args) {
        //ConfigurableApplicationContext:IOC容器类,可以查询和获取容器内的所有对象
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        Car car = run.getBean("car", Car.class);
        System.out.println(car);//Car{brand='BT-t77', price=100000.0}
    }
}

@EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties(Xxx.class)

  • 功能1:开启 Xxx 类的配置绑定。
  • 功能2:创建该类对象并添加到容器中。对象的 id 为prefix-对象全类名
  • 该注解要使用在任一配置类上。

@ConfigurationProperties(prefix="xxx"):进行属性绑定。

SpringBootConfig.java

@Configuration(proxyBeanMethods=true)//声明该类为配置类
@EnableConfigurationProperties(Car.class)
//添加到容器中的Car组件的id为:bean.car-com.mcc.springboot.bean.Car
public class SpringBootConfig {

}

Car.java

package com.mcc.springboot.bean;

@ConfigurationProperties(prefix = "bean.car")
public class Car {
    private String brand;
    private double price;
}

MainApplication.java

@SpringBootApplication(scanBasePackages="com.mcc.springboot")//声明该类为主类
public class MainApplication {
    public static void main(String[] args) {
        //ConfigurableApplicationContext:IOC容器类,可以查询和获取容器内的所有对象
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); 
        Car car = run.getBean("bean.car-com.mcc.springboot.bean.Car", Car.class);
        System.out.println(car);//Car{brand='BT-t77', price=100000.0}
    }
}

配置原则以及修改默认配置

SpringBoot 默认会在底层配好所有的组件,但如果用户自己配置了相同的组件,则以用户配置的优先。

有两种方法更改 SpringBoot 的默认配置,以 CharacterEncodingFilter 为例:
(1)使用 @Bean 注解替换底层组件。

@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter (){
    CharacterEncodingFilter filter = new CharacterEncodingFilter();
    filter.setEncoding("GBK");
    return filter;
}

(2)修改 application.properties 中对应的属性。 因为 SpringBoot 提供的组件都要加载配置文件中的属性,因此修改配置文件中的属性即可。

server.servlet.encoding.charset=GBK

那么,如何查找组件要加载的属性呢?

  1. 查找官方文档

  2. 第1种情况:
    配置中有 @ConditionalOnProperty 时,查看注解的 prefix 值即可。
    第2种情况:
    配置中没有 @ConditionalOnProperty 时,进入 @EnableConfigurationProperties 的属性,查看 @ConfigurationProperties 的 prefix 值即可。
    在这里插入图片描述

debug=true

查看当前项目中哪些配置生效,哪些配置没有生效:
在 application.properties 中,使用属性debug=true,开启自动配置报告。Positive—生效,Negative—不生效。
在这里插入图片描述

Lombok

使用 Lombok 提供的注解,可以简化 JavaBean 的开发过程。

实现方式:

  1. 引入 Lombok 依赖。

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId> 
    </dependency>
    
  2. 安装 Lombok 插件。
    在这里插入图片描述

  3. 使用下述注解,简化 JavaBean 的开发。

注解作用
@NoArgsConstructor无参构造器
@AllArgsConstructor全参构造器,部分参数的构造器需要手动创建
@Datagetter()、setter() 方法
@ToStringtoString() 方法
@EqualsAndHashCodeequals()、hashCode() 方法
@slf4j引入日志类,可以使用 log 对象中的方法,如log.info("xxx"),相当于System.out.println()
  1. 修改后的 User.java(其他 Bean 相同)。

    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    @ToString
    public class User {
        private String username;
        private Phone phone;
    
        //创建一个只有username的部分参数构造器
        public User(String username){
            this.username = username;
        }
    }
    

在这里插入图片描述

devtools

devtools(developer tools),自动重启项目工具。
当项目中的代码修改后,按Ctrl+F9,即可自动重启项目。

实现方式:

  1. 引入 devtools 依赖。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    
  2. 当项目中的代码修改后,按Ctrl+F9,重启项目。

Spring Initailizr — 项目初始化向导

在这里插入图片描述

yaml

介绍

SpringBoot 的配置文件有两种格式选择:application.properties 和 application.yaml(yml)

yaml 语言适合用来做以数据为中心的配置文件。

语法

  • key: value k v之间有空格
  • 区分大小写
  • 使用缩进表示层级关系
  • 缩进不允许使用 tab,只允许使用空格
  • 缩进的空格数不重要,只要相同层级的元素左对齐即可
  • ‘#’ 表示注释
  • 字符串无需加引号
  • JavaBean 中驼峰类型的属性,在 yaml 中最好用-x代替大写字母。如,userName => user-name

数据类型

  • 数值型,字符串:k: v

  • 对象,Map 集合:

    k: {k1: v1,k2: v2,k3: v3}
    或
    k: 
      k1: v1
      k2: v2
      k3: v3
    
  • 数组,Set 集合,List 集合

    k: [v1,v2,v3]
    或
    k:
     - v1
     - v2
     - v3
    

举例

@Data
@Component
@ConfigurationProperties(prefix = "person")//注意:prefix中不能用驼峰写法
public class Person {
    
    private String userName;
    private Boolean boss;
    private Date birth;
    private Integer age;
    private Pet pet;
    private String[] interests;
    private List<String> animal;
    private Map<String, Object> score;
    private Set<Double> salarys;
    private Map<String, List<Pet>> allPets;
}

@Data
public class Pet {
    private String name;
    private Double weight;
}

application.yaml

person:
  userName: 张三
  boss: false
  birth: 2019/12/12 20:12:33
  age: 18
  pet: 
    name: tomcat
    weight: 23.4
  interests: [篮球,游泳]
  animal: 
    - jerry
    - mario
  # Map<String,Map<String,int>> score
  score:
    English: 
      first: 90
      second: 95
      third: 100
    math: [131,140,148]
    chinese: {first: 128,second: 136}
  salarys: [11000,12000,13000]
  # Map<String, List<Pet>> allPets
  allPets:
    sick:
      - {name: tom}
      - {name: jerry,weight: 47}
    health: [{name: mario,weight: 47},{name: jack,weight: 45}]

配置文件代码提示

在 pom.xml 中添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

在将项目打包时,不将上述提示代码的 jar 包打包:

<plugin>
   <!--简化部署的插件:将工程打成可执行的jar包-->
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <!--打包时不打包配置文件提示(处理器)包-->
        <excludes>
            <exclude>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
            </exclude>
        </excludes>
    </configuration>
</plugin>

注意:
该代码提示功能,会将 JavaBean 中驼峰类型的属性提示为-x。如,userName 提示为 user-name。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值