springboot学习笔记-基础,自动配置与开发插件

简介

感觉学这种框架开发还是要经常写博客记录一些问题,自己的博客嘛,反正是菜鸡也不建议乱一点hhh

spring文档:https://docs.spring.io/spring-boot/docs/current/reference/html/index.html

spring,springmvc,springboot的一些知识:https://www.yijiyong.com/spring/basic/01-intro.html

底层注解

一些常见的底层注解

自动引导配置

@SpringBootApplication

@SpringBootApplication
等同于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(“com.atguigu.boot”)

组件添加

@Configuration

@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件

  • 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
  • 2、配置类本身也是组件
  • 3、proxyBeanMethods:代理bean的方法
  • Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
  • Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
  • 组件依赖必须使用Full模式默认。其他默认是否Lite模式

@Bean

注册组件:自己编写Config类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Configuration(proxyBeanMethods = false)
public class MyConfig {

@Bean
public Car car01(){
Car car = new Car("benz",1000000000);
return car;
}

@Bean("User001")
public User user01(){
User user = new User("Tom",20);
user.setPet(new Pet("zhutousan"));
return user;
}
}

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
//返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

//从容器中获得组件
User user001 = run.getBean("User001", User.class);
System.out.println(user001.getPet());

//获取Config组件
MyConfig config = run.getBean( MyConfig.class);
Car car = config.car01();

System.out.println(car);

}
}

@Import、@ComponentScan

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}

@Conditional

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

@Import({User.class, DBHelper.class})
给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名

@ConditionalOnBean(name = “tom”)
@ConditionalOnMissingBean(name = “tom”)

原生配置文件导入

@ImportResource

支持原生配置文件

@ImportResource(“classpath:beans.xml”)

beans.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
======================beans.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<bean id="haha" class="com.atguigu.boot.bean.User">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>

<bean id="hehe" class="com.atguigu.boot.bean.Pet">
<property name="name" value="tomcat"></property>
</bean>
</beans>

配置绑定

@ConfigurationProperties

只有在容器中的组件,才会拥有SpringBoot提供的强大功能
@Component
@ConfigurationProperties(prefix = “mycar”)

@EnableConfigurationProperties

@EnableConfigurationProperties(Car.class)
//1、开启Car配置绑定功能
//2、把这个Car这个组件自动注册到容器中

自动配置原理

@SpringBootApplication

Springboot的启动项:

这是一个合成注解,由

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan

合成而来

1
2
3
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {

image.png

@SpringBootConfiguration

@Configuration表明他是一个config类

因此其实我们的主启动类MainAppliciation也是一个配置类

image.png

因此这样也是可以的

image.png

@EnableAutoConfiguration

1
2
3
4
5
6
7
8
9
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

Class<?>[] exclude() default {};

String[] excludeName() default {};
}

分别跟进

@AutoConfigurationPackage

1
2
3
4
5
6
@Import({Registrar.class})
public @interface AutoConfigurationPackage {
String[] basePackages() default {};

Class<?>[] basePackageClasses() default {};
}

这里导入了org.springframework.boot.autoconfigure.AutoConfigurationPackages.Registrar

在这个方法打上断点,在这里批量注册组件

image.png

metadata封装了注解的元信息,可以看到注解中的信息被封装在com.xianbei.boot.MainApplication

image.png

(new AutoConfigurationPackages.PackageImports(metadata)).getPackageNames()的结果就是我们的包名

这个包名也是对应了上面注解封装类的包

image.png

因此这里就是自动将com.xianbei.boot包下的组件注册到容器中去

@Import({AutoConfigurationImportSelector.class})

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports方法返回一个数组

1
2
3
4
5
6
7
8
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}

其中,跟进getAutoConfigurationEntry方法,并打上断点调试

image.png

这里的配置项也是写好的,位于spring-boot-autoconfigure-2.6.6.jar\META-INF\spring.factories

但他实际上还是按需加载类的,这就是基于 springboot 的按条件装配@Conditional,根据规则最终实现按需装配。

image.png