- 引入tomcat依赖
org.springframework.boot spring-boot-starter-tomcat2.3.12.RELEASE compile
- 配置Tomcat
- 引入springMVC 全套组件
- 自动配好SPringleMVC常用组件
org.springframework spring-web5.2.15.RELEASE compile org.springframework spring-webmvc5.2.15.RELEASE compile
- 常用的功能
- dispatchServlet(转发)
- multipartResolver(文件上传)
- ViewResolver(视图解决器)
- characterEncodingFilter(文字过滤器)
- 展示容器内 对应组件的方法
@SpringBootApplication public class MainApplication { public static void main(String[] args) { // springApplication.run(MainApplication.class,args); // 1.返回IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); // 2.查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for(String name : names){ System.out.println(name); } } }1.3 默认包结构
-
主程序所在包的所有子包组件都会被默认扫描进来
```
com
± example
± myapplication
± Application.java
|
± customer
| ± Customer.java
| ± CustomerController.java
| ± CustomerService.java
| ± CustomerRepository.java
|
± order
± Order.java
± OrderController.java
± OrderService.java
± OrderRepository.java
``` -
无需以前的包扫瞄
-
如果要自己设置包扫描
@SpringBootApplication(scanbasePackages = "com.atguigu") //在主类上添加 @ComponentScan //在具体类上添加包扫描的注解 注意不能再包SpringBootApplication上添加包扫描注解,因为SpringBootApplication上已经有了componentScan注解了
- *@SpringBootApplication是复合类
@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan1.4 自动配置有很多的默认值
- 默认配置都是最终映射到一个类的
- 配置文件的值最终会绑定到每个类上,这个类在容器中创建对象
- 非常多的starter
- 引入了那些场景这个场景的自动配置才会开启
- SpringBoot所有自动配置功能都依赖于spring-boot-autoconfigure
-
springboot web项目需要引入spring-boot-starter-web依赖
-
spring-boot-starter-web依赖于spring-boot-starter
-
spring-boot-starter需要spring-boot-autoconfigure完成自动配置
2. 容器功能 2.1 组件添加org.springframework.boot spring-boot-autoconfigure2.3.12.RELEASE compile
-
@Configuration(告诉IOC本类为配置类)
@Configuration(proxyBeanMethods = false) //告诉SpringBoot 这是一个配置类 == 配置文件 //配置文件能完成的事情 配置类都可以完成 //同时@Configuration创建的组件也是被加载到容器中的 //默认创建的组件都是单实例的 public class MyConfig { @Bean //给容器中添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例 public User user01(){ return new User("张三"); } @Bean("tomcat111") public Pet getPet(){ return new Pet("tomcat","12"); } }
-
在Configuration注解的类所注册的组件都是单例的原因
// Configuration.class @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @documented @Component public @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true; //默认是true就表明了方法会被代理 }
- proxyBeanMethods方法:代理bean方法 ```java Full(proxyBeanMethods = true) //使用代理的方法,单例,返回相同的对象,应用于组件依赖 Lite(proxyBeanMethods = false) //多例每次返回不同对象,优点:跳过检查容器,springboot启动快
-
-
@Bean,@Component,@Controller,@Service,@Repository
-
@ComponentScan,@import
@import必须写在包扫描范围中,导入的时一个数组,他导入组件的组件名字,是包名+类名
- @Conditional:条件装配,满足Conditional才装入容器
较为重要的 ConditionalOnBean() //容器中有这个类,才注册组件 ConditionalOnMissingBean //容器中没有这个组件,才注册组件 ConditionalOnMissingClass //容器中没有这个才注册组件 ConditionalOnClass //容器中有这个类才注册组件 ConditionalOnResource //文件中具有某个资源的时候才干什么 ConditionalOnJava //默认某一java版本,才注册组件 ConditionalOnWebApplication //是web应用的时候,才注册组件 ConditionalOnNotWebApplication //不是web应用的时候,才注册组件 ConditionalOnProperty //组件有了有个属性的时候,才注册组件
示例
@Configuration //告诉SpringBoot 这是一个配置类 == 配置文件 //配置文件能完成的事情 配置类都可以完成 //同时@Configuration创建的组件也是被加载到容器中的 //默认创建的组件都是单实例的 public class MyConfig { @ConditionalOnMissingBean(name = "tomcat") @Bean //给容器中添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例 public User user01(){ return new User("张三"); } public Pet getPet(){ return new Pet("tomcat","12"); } }2.2 原生配置文件的导入
-
@importResource**:写在配置类上**
用来将xml配置文件对象导入到springboot的IOC容器中
@Configuration //告诉SpringBoot 这是一个配置类 == 配置文件 @importResource("classpath:beans.xml") public class MyConfig { @Bean //给容器中添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例 public User user01(){ return new User("张三"); } }
- ConfigurationProperties
@Component //一定要加入组件注释,让组件加入容器之中 @ConfigurationProperties(prefix = "mycar") //设置前缀,会在application.properties去查找 public class Car { private String brand; private String price; public void setBrand(String brand) { this.brand = brand; } public void setPrice(String price) { this.price = price; } public String getBrand() { return brand; } public String getPrice() { return price; } @Override public String toString() { return "Car{" + "brand='" + brand + ''' + ", price='" + price + ''' + '}'; } }
- @EnableCofigurationProperties + @ConfigurationProperties
@Configuration @EnableConfigurationProperties(Car.class) //使文件可以 public class MyConfig { @Bean //给容器中添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值就是组件在容器中的实例 public User user01(){ return new User("张三"); } public Pet getPet(){ return new Pet("tomcat","12"); } } @ConfigurationProperties(prefix = "mycar") //设置前缀,会在application.properties去查找 public class Car { private String brand; private String price; public void setBrand(String brand) { this.brand = brand; } public void setPrice(String price) { this.price = price; } public String getBrand() { return brand; } public String getPrice() { return price; } @Override public String toString() { return "Car{" + "brand='" + brand + ''' + ", price='" + price + ''' + '}'; } }
方法一主要用于自己编写的类,方法主要用于引入第三方的类的数据绑定
3. 自动配置原理入门 3.1 SpringBootApplication 完整签名(idea:ctrl+n进行搜索)@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( //三个为其核心注解 或者说SpringbootApplication是他们三个的复合 excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication
- @SpringBootConfiguration
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @documented @Configuration //代表当前是一个配置类,那么说明SpringBootApplication依然是个配置类,依然是核心配置类 @Indexed public @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true; }
- @ComponentScan
指定扫描那些包,具体可以看Spring注解;
- @EnableAutoConfiguration(重点,指定默认的包规则)
作用:帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot,并创建对应配置类的Bean,并把该Bean实体交给IoC容器进行管理。
@AutoConfigurationPackage @import({AutoConfigurationimportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class>[] exclude() default {}; String[] excludeName() default {}; }
- AutoConfigurationPackage自动配置包
@import({AutoConfigurationPackages.Registrar.class}) //给容器中导入一个组件 public @interface AutoConfigurationPackage { String[] basePackages() default {}; Class>[] basePackageClasses() default {}; }
使用import导入一个registrar的意义:批量导入一些组件
- 查看AutoConfigurationPackages.Registrar.class,了解registrar注册了什么。
public abstract class AutoConfigurationPackages { private static final Log logger = LogFactory.getLog(AutoConfigurationPackages.class); private static final String BEAN = AutoConfigurationPackages.class.getName(); public AutoConfigurationPackages() { } ... ... ... static class Registrar implements importBeanDefinitionRegistrar, Determinableimports { Registrar() { } public void registerBeanDefinitions(Annotationmetadata metadata, BeanDefinitionRegistry registry) { AutoConfigurationPackages.register(registry, (String[])(new AutoConfigurationPackages.Packageimports(metadata)).getPackageNames().toArray(new String[0])); } public Set
- @import({AutoConfigurationimportSelector.class})
重点在AutoConfigurationimportSelector.class->selectimports->this.getAutoConfigurationEntry(annotationmetadata),给容器中批量导入组件
protected AutoConfigurationimportSelector.AutoConfigurationEntry getAutoConfigurationEntry(Annotationmetadata annotationmetadata) { if (!this.isEnabled(annotationmetadata)) { return EMPTY_ENTRY; } else { AnnotationAttributes attributes = this.getAttributes(annotationmetadata); List3.2 按需配置configurations = this.getCandidateConfigurations(annotationmetadata, attributes); //1.getCandidateConfigurations获取到需要导入到容器中的配置类(组件) //2.SpringFactoriesLoader.loadFactoryNames,spring的工厂加载器,来加载一些配置类 //利用工厂加载器的private static Map > loadSpringFactories(@Nullable ClassLoader classLoader)方法,获得所有组件 //3.loadSpringFactories方法会在meta-INF/spring.factories位置加载一个文件。 // 扫描当前系统中所有meta-INF/spring.factories // 核心jar包中 spring-boot-autoconfigure-2.3.12.RELEASE.jar 含有127个元素springboot一启动 就需要给容器加载的所有类。 configurations = this.removeDuplicates(configurations); Set exclusions = this.getExclusions(annotationmetadata, attributes); this.checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = this.getConfigurationClassFilter().filter(configurations); this.fireAutoConfigurationimportEvents(configurations, exclusions); return new AutoConfigurationimportSelector.AutoConfigurationEntry(configurations, exclusions); } }
由上面知道了,springboot启动时,如何进行自动配置中找到相应其的组件,但是不是所有的组件都是必须加载到组件当中的,存在按需配置的情况(以上的autoconfigure中127个没有全部加载,需要导入相应的场景依赖,即条件装配规则)
换句话说:127个场景的所有自动配置启动的时候全部加载,但是并没有全部装配
3.3 修改默认配置@Bean @ConditionalOnBean({MultipartResolver.class}) //容器中有这类组件 @ConditionalOnMissingBean( //容器中没有这个名字 name = {"multipartResolver"} ) public MultipartResolver multipartResolver(MultipartResolver resolver) { //@Bean标注的方法传入了对象参数,这个参数值就会从容器中中找 // SpringMvc multipartResolver,放置有些用户配置的文件上传解析器不符合规范 return resolver; } //给容器中加入了文件上传解析器4.总结
- SpringBoot先加载所有的自动配置类
- 每个自动配置类按照条件生效
- 生效的配置类都会按照容器中装配很多组件
- 只要让其中有这些组件,相当于这些功能就有了
- 只要用户有自己的配置的,就以用户的优先
xxxxAutoConfiguration—>组件—>xxxxProperties里面哪值---->application.properties
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)