Spring Boot学习笔记总结
Posted IT_Holmes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot学习笔记总结相关的知识,希望对你有一定的参考价值。
文章目录
- 1. SpringBoot底层注解 @Configuration
- 2. SpringBoot底层注解 @import注解
- 3. SpringBoot底层注解 @Conditional注解
- 4. SpringBoot底层注解 @ImportResource
- 5. SpringBoot底层注解 @ConfigurationProperties
- 6. @SpringBootApplication注解源码分析
- 7. SpringBoot的自动配置流程
- 8. 总结 自动配置流程原理
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于你而言就是小菜一碟