Spring Boot学习笔记总结

Posted IT_Holmes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot学习笔记总结相关的知识,希望对你有一定的参考价值。

文章目录

1. SpringBoot底层注解 @Configuration

1.1 @Configuration 和 @Bean的作用


配置类,必须能让SpringBoot扫描到才能装配到容器中!

创建一个MyConfig类,作为配置类:

  • @Configuration注解作用:告诉springboot这是一个配置类。等同于我们创建了一个spring.xml配置文件。
  • @Bean注解作用:给容器中添加bean对象(组件)。相当于在spring.xml文件中创建了一个bean对象。
    • 方法名就是对应bean对象(组件)的id。
    • 返回值类型就是bean对象(组件)的类型。
    • 返回的值就是bean对象(组件)在容器中的实例。
  • 配置类本身也是一个对象(组件),也会被注入到容器中。
package com.itholmes.boot.config;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration注解作用:告诉springboot这是一个配置类。等同于我们创建了一个spring.xml配置文件。
@Configuration
public class MyConfig 

    /*
        @Bean注解作用:给容器中添加bean对象(组件)。相当于在spring.xml文件中创建了一个bean对象。
            方法名就是对应bean对象(组件)的id。
            返回值类型就是bean对象(组件)的类型。
            返回的值就是bean对象(组件)在容器中的实例。
    */
    @Bean
    public User user01()
        return new User("张三",18);
    

    @Bean
    public Pet tomcatPet()
        return new Pet("tomcat");
    


MainApplication,主程序类中,可以获取对应的bean对象(组件):

  • SpringApplication.run(MainApplication.class, args)的返回值就是ioc容器。
  • 可以直接getBean获取容器中的对象(组件),验证上面的注解类。
package com.itholmes.boot;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import com.itholmes.boot.config.MyConfig;
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;

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages="com.itholmes")
public class MainApplication 
    public static void main(String[] args) 

        //1. 返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //2. 查看容器里面的组件(就是bean的对象)
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) 
            System.out.println(name);
        

        //3. 从容器中获取组件。
        Pet pet = run.getBean("tomcatPet", Pet.class);
        User user01 = run.getBean("user01", User.class);
        User user02 = run.getBean("user01", User.class);

1.2 @Configuration注解的 proxyBeanMethods参数变量

1.2.1 @Configuration(proxyBeanMethods = true)


SpringBoot2的@Configuration比SpringBoot1版本多了一个proxyBeanMethods 参数。

proxyBeanMethods注解,英文直译过来就是代理bean方法。其实就是告诉SpringBoot当前的配置类是否生成代理对象。

从容器中,获取配置类对象,如果@Configuration(proxyBeanMethods = true(默认就是true)) ,那么生成的就是代理对象。代理对象每次执行方法的时候都是先去容器中拿对象(组件),没有才会创建。

 // 返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

// 配置类本身也是一个对象(组件)
MyConfig myConfig = run.getBean(MyConfig.class);

System.out.println(myConfig);
//com.itholmes.boot.config.MyConfig$$EnhancerBySpringCGLIB$$f2269e91@5e7c141d

打印出的代理对象,一般都会带着$$这样的标识。

这里的代理对象,无论调用多少次对象中的方法,拿到的依然是组件里面的单例对象。

总之,被@Configuration(proxyBeanMethods = true)修饰的配置类,SpringBoot会生成一个代理对象,每一个代理对象都先会先去容器中拿对象,也就是所谓的单例模式的效果。

1.2.2 @Configuration(proxyBeanMethods = false)


@Configuration(proxyBeanMethods = false),设置为了false,就不会在容器中创建代理对象。当然每一次调用方法,都会产生一个新的对象,也就是契合了多例模式。


SpringBoot2 @Configuration新增的两个模式:

  • full (全配置模式) proxyBeanMethods = true , 被修饰的配置类,SpringBoot会生成一个代理对象并装配到容器中。每次代理对象,都会先检查容器有没有。
  • Lite (轻量级配置模式) proxyBeanMethods = false , 不会生成代理对象。

full模式,因为只要外部调用代理对象方法,代理对象会不断的检查容器中是否有,这个过程很浪费时间。

1.3 什么时候proxyBeanMethods设置为true,什么时候设置false?


当有容器中,有组件(对象)依赖的时候,会将proxyBeanMethods设置为true。

当有容器中,没有组件(对象)依赖会设置为false。


什么是组件依赖?

  • 相当于我在xml文件中创建了两个bean,但是其中有一个bean对象的内部属性依赖于另一bean。

例如:

在User实体类中,创建一个Pet实体类的成员变量。

package com.itholmes.boot.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User 
    String name;
    int age;
    Pet pet;

MyConfig类的proxyBeanMethods设置为true,就可以识别到容器中的对象。这样就可以实现组件依赖。

package com.itholmes.boot.config;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration(proxyBeanMethods = true)
public class MyConfig 

    @Bean
    public User user01()
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        //依赖于tomcatPet方法,注入容器的对象。
        user.setPet(tomcatPet());
        return user;
    

    @Bean
    public Pet tomcatPet()
        return new Pet("tomcat");
    


package com.itholmes.boot;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import com.itholmes.boot.config.MyConfig;
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;

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages="com.itholmes")
public class MainApplication 
    public static void main(String[] args) 

        //返回IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        //查看容器里面的组件(就是bean的对象)
        String[] names = run.getBeanDefinitionNames();
        for (String name : names) 
            System.out.println(name);
        

        //从容器中获取组件。
        Pet pet = run.getBean("tomcatPet", Pet.class);
        User user = myConfig.user01();

        System.out.println("测试是否是同一个bean对象:"+(user.getPet() == pet));
        //测试是否是同一个bean对象:true
    

2. SpringBoot底层注解 @import注解


@Import(User.class,Dog.class)就会给容器注入一个无参的User类和Dog类。

  • 在任何类都可以用它修饰装配到容器中,前提是这个类一定要被SpringBoot扫描到!
  • 被装配的类的名字是对应的全类名(路径加类名),例如:com.itholmes.boot.bean.User。
package com.itholmes.boot.config;

import com.itholmes.boot.bean.Dog;
import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/*
    @Import(User.class,Dog.class)
        给容器中自动创建出这两个类型的组件。
*/
@Import(User.class, Dog.class)
@Configuration(proxyBeanMethods = true)
public class MyConfig 

    @Bean
    public User user01()
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        //依赖于tomcatPet方法,注入容器的对象。
        user.setPet(tomcatPet());
        return user;
    

    @Bean
    public Pet tomcatPet()
        return new Pet("tomcat");
    


主程序类,测试:

package com.itholmes.boot;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import com.itholmes.boot.config.MyConfig;
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;

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages="com.itholmes")
public class MainApplication 
    public static void main(String[] args) 

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

        Pet pet = run.getBean("tomcatPet", Pet.class);
        User user01 = run.getBean("user01", User.class);

        //getBeanNamesForType(xxx)方法会获取所有xxx.class类型的参数。
        String[] users = run.getBeanNamesForType(User.class);
        for (String user : users) 
            System.out.println(user);
        

        //com.itholmes.boot.bean.User 一个是对应@import注入
        //user01 一个是对应@Bean注入

    

3. SpringBoot底层注解 @Conditional注解


@Conditional注解:条件装配,满足Conditional指定的条件,则进行组件装配和注入。

再例如,@ConditionalOnBean注解使用。

  • @ConditionalOnBean(name=“tom”)注解:意思是当name中的有id为tom的对象组件的时候,再装配user01这个组件对象。
package com.itholmes.boot.config;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
    @ConditionalOnBean注解:意思是当name中的有id为tom的对象组件的时候,再装配user01这个组件对象。
*/

//修饰到类上面,就是如果容器中,没有id为tom的对象组件,则类下面方法都不会装配到容器中。
//@ConditionalOnBean(name="tom")
@Configuration(proxyBeanMethods = true)
public class MyConfig 


    @ConditionalOnBean(name="tom") //修饰到方法上,如果容器中,没有id为tom对象组件,则该方法不会装配到容器中。
    @Bean("user")
    public User user01()
        User user = new User();
        user.setName("张三");
        user.setAge(18);
        //依赖于tomcatPet方法,注入容器的对象。
        user.setPet(tomcatPet());
        return user;
    

    //@Bean("tom")//这里注释了@Bean注解,这样该方法就不会被装配到容器中。
    public Pet tomcatPet()
        return new Pet("tomcat");
    


package com.itholmes.boot;

import com.itholmes.boot.bean.Pet;
import com.itholmes.boot.bean.User;
import com.itholmes.boot.config.MyConfig;
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;

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages="com.itholmes")
public class MainApplication 
    public static void main(String[] args) 

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

        //containsBean方法:判断容器中是否包含一个id为tom的组件对象。
        boolean user = run.containsBean("user");
        System.out.println("判断容器中,是否还有user的组件对象:"+user);

        boolean tom = run.containsBean("tomcatPet");
        System.out.println("判断容器中,是否还有tom的组件对象:"+tom);

		//判断容器中,是否还有user的组件对象:false
		//判断容器中,是否还有tom的组件对象:false
		
    

这些当什么什么才会装配到容器。一般用在SpringBoot的底层中,经常使用!

4. SpringBoot底层注解 @ImportResource


有些使用,可能还是会用到xml配置文件,那么想要让该xml配置,装配到springboot的ioc容器中的话,就可以使用@ImportResource注解来装配。

5. SpringBoot底层注解 @ConfigurationProperties

5.1 方式一:@Component注解 + @ConfigurationProperties注解


方式一:两个注解都用到实体类中。

@Component注解 + @ConfigurationProperties注解:

  • 使用@Component注解装配到容器中。
  • @ConfigurationProperties(prefix = “mycar”)注解:
    就可以在application.properties配置文件中拿到前缀为mycar对应属性的值。将这些值注入到对应的容器组件对象中。

创建一个Car类:

package com.itholmes.boot.bean;

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

/*
    只有容器中的组件,才会拥有SpringBoot提供的强大功能。所以使用@Component注解装配到容器中。

    @ConfigurationProperties(prefix = "mycar")注解:
        就可以在application.properties配置文件中拿到前缀为mycar对应属性的值。将这些值注入到对应的组件对象中。
*/
@Component//先将当前的类,装配到容器中。
@ConfigurationProperties(prefix = "mycar")
public class Car 
    private String brand;
    private Integer price;

    public String getBrand() 
        return brand;
    

    public void setBrand(String brand) 
        this.brand = brand;
    

    public Integer getPrice() 
        return price;
    

    public void setPrice(Integer price) 
        this.price = price;
    

    @Override
    public String toString() 
        return "Car" +
                "brand='" + brand + '\\'' +
                ", price=" + price +
                '';
    

application.properties配置文件:

# 修改端口号
server.port=8888

# 相当于将下面的两个属性内容,注入到了对应的组件对象中。
mycar.brand=BYD
mycar.price=100000

这样就相当于在容器中装配了对象,并且给该对象注入了相关信息。

5.1 方式二:@EnableConfigurationProperties(Car.class)注解 + @ConfigurationProperties注解


方式二:@ConfigurationProperties注解用于实体类,@EnableConfigurationProperties(Car.class)注解用于配置类中。

  • @ConfigurationProperties注解作用同上。
  • @EnableConfigurationProperties(Car.class)注解,1.开启Car配置绑定功能,也就是读取properties文件。2.把这个Car这个组件自动注册到容器中。

Car实体类:

package com.itholmes.boot.bean;

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

/*
    只有容器中的组件,才会拥有SpringBoot提供的强大功能。所以使用@Component注解装配到容器中,如果配置类中有@EnableConfigurationProperties(Car.class)也可以是可以装配到容器中,并且注入属性的。

    @ConfigurationProperties(prefix = "mycar")注解:
        就可以在application.properties配置文件中拿到前缀为mycar对应属性的值。将这些值注入到对应的容器组件对象中。
*/
@ConfigurationProperties(prefix = "mycar")
public class Car 
    private String brand;
    private Integer price;

    public String getBrand() 
        return brandSpring Boot学习笔记总结

Spring Boot学习笔记总结

看完这份学习笔记,Spring Boot于你而言就是小菜一碟

Spring Boot学习笔记:简介与HelloWorld搭建

Spring Boot学习总结一

Spring Boot学习笔记