1. SpringBoot好处
- 不使用SpringBoot的时候我们搭建Spring项目的流程:
- pom文件中引入相关jar包,包括spring、springmvc、redis、mybaits、log4j、mysql-connector-java 等等相关jar …
- 配置web.xml,Listener配置、Filter配置、Servlet配置、log4j配置、error配置 …
- 配置数据库连接、配置spring事务
- 配置视图解析器
- 开启注解、自动扫描功能
- 配置完成后部署tomcat、启动调试
- 使用之后搭建项目的流程:
- 添加依赖
- 添加配置文件–基本属性
- 添加启动类
2.starter启动器
- 作用:
- spring-boot-starter-web包自动帮我们引入了web模块开发需要的相关jar包。
- mybatis-spring-boot-starter帮我们引入了dao开发相关的jar包。
- spring-boot-starter-xxx是官方提供的starter,xxx-spring-boot-starter是第三方提供的starter。
- 机制:引入的xx-starter本质是jar包,在打开项目的外部依赖jar包的时候发现引入的就是配置文件引入其他jar的pom文件
- 替代: 我们可以自己加上配置文件,加上配置类,并且利用注解实现Spring容器启动的时候进行自动加载,从而替代starter包??
3. 初始化时候的自动配置
- 原理: 带有starter的jar包多会引入一个xxx-autoconfigure的包,该包下面会有XXXAutoConfiguration类,在这个类中有@Bean和@Configuration两个注解,这两个注解一起使用就可以创建一个基于java代码的配置类,可以用来替代相应的xml配置文件。根据Spring启动的时候回家再配置文件的性质,我们知道springBoot在项目启动的时候通过sarter就能够将XXXAutoConfiguration中的Bean注入
- @Configuration:含有该注解的类,在被扫描之后可以看做生产了让Spring IoC容器管理的Bean实例的工厂
- @Bean注解:告诉Spring,被@Bean注解的方法将返回一个对象,该对象应该被注册到spring容器中。
- 所以含有starter的jar中包含的子Jar或配置类就实现了创建Bean工厂,并且将Bean注册到spring容器中
4. 自动配置的条件:
- 条件依赖注解:
- @ConditionalOnBean,仅在当前上下文中存在某个bean时,才会实例化这个Bean
- @ConditionalOnClass,某个class位于类路径上,才会实例化这个Bean。
- @ConditionalOnBean,仅在当前上下文中存在某个bean时,才会实例化这个Bean
- @ConditionalOnExpression,当表达式为true的时候,才会实例化这个Bean
- @ConditionalOnMissingBean,仅在当前上下文中不存在某个bean时,才会实例化这个Bean
- @ConditionalOnMissingClass,某个class在类路径上不存在的时候,才会实例化这个Bean。
- @ConditionalOnNotWebApplication,不是web应用时才会实例化这个Bean。
- @AutoConfigureAfter,在某个bean完成自动配置后实例化这个bean。
- @AutoConfigureBefore,在某个bean完成自动配置前实例化这个bean。
举例说明:
说明自动配置类中的Bean(logger/MybatisProperties/ResourceLoader等)要进行注入,必须满足条件:
- 类路径中存在SqlSessionFactory.class、SqlSessionFactoryBean.class这两个类
- 存在DataSource这个bean且这个bean完成自动注册
- DataSourceAutoConfiguration要完成自动配置,进入DataSourceAutoConfiguration这个类,可以看到这个类属于这个包:org.springframework.boot.autoconfigure.jdbc,这个包又属于spring-boot-autoconfigure-2.0.4.RELEASE.jar这个包,自动配置这个包帮我们引入了jdbc、kafka、logging、mail、mongo等包。很多包需要我们引入相应jar后自动配置才生效。
- 等等
5. 如何通过配置文件生成数据源
- 疑问:springboot是如何读取yml或者properites配置文件的的属性来创建数据源的(仍然使用上面的例子)
- 在DataSourceAutoConfiguration类里面,使用了EnableConfigurationProperties这个注解
- DataSourceProperties中封装了数据源的各个属性,且使用了注解ConfigurationProperties指定了配置文件的前缀
- 总结:@ConfigurationProperties注解的作用是把yml或者properties配置文件转化为bean。
@EnableConfigurationProperties注解的作用是使@ConfigurationProperties注解生效。如果只配置@ConfigurationProperties注解,在spring容器中是获取不到yml或者properties配置文件转化的bean的。
6.依赖包中的bean如何发现并被加载?
- 问题:springboot默认扫描启动类所在的包下的主类与子类的所有组件,但并没有包括依赖包的中的类,那么依赖包中的bean是如何被发现和加载的?
- 观察SpringBootApplication注解:住家的注解成为元注解,这里的元注解中比较重要的有下面几个注解:
- @Configuration(@SpringBootConfiguration点进去还是@Configuration和
- @ComponentScan([自动扫描并加载符合条件的组件,比如@Component和@Repository等,最终将这些bean定义加载到spring容器中)
- @EnableAutoConfiguration(重要!!!借助@Import的支持,收集和注册依赖包中相关的bean定义)
- @EnableAutoConfiguration注解引入了@AutoConfigurationPackage和@Import这两个注解
- @AutoConfigurationPackage的作用就是自动配置的包。
- @Import导入需要自动配置的组件,@EnableAutoConfiguration注解中使用了@Import({AutoConfigurationImportSelector.class})注解,AutoConfigurationImportSelector实现了DeferredImportSelector接口,DeferredImportSelector接口继承了ImportSelector接口,ImportSelector接口只有一个selectImports方法。selectImports方法返回一组bean,springboot正式通过这种机制来完成bean的注入的。
- 实现:进入 AutoConfigurationImportSelector类,我们可以发现SpringFactoriesLoader.loadFactoryNames方法调用loadSpringFactories方法从所有的jar包中读取META-INF/spring.factories文件信息。
下面是spring-boot-autoconfigure这个jar中spring.factories文件部分内容,其中有一个key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的值定义了需要自动配置的bean,通过读取这个配置获取一组@Configuration类 - 每个xxxAutoConfiguration都是一个基于java的bean配置类。实际上,这些xxxAutoConfiguratio不是所有都会被加载,会根据xxxAutoConfiguration上的@ConditionalOnClass等条件判断是否加载;通过反射机制将spring.factories中@Configuration类实例化为对应的java实列。
7.总结:普通类交给Spring容器管理,通常有以下方法:
- 使用 @Configuration与@Bean 注解
- 使用@Controller @Service @Repository @Component 注解标注该类,然后启用@ComponentScan自动扫描
- 使用@Import 方法
springboot中使用了@Import 方法,使用@ComponentScan的作用就是自动扫描并加载符合条件的组件,比如@Component和@Repository等,最终将这些bean定义加载到spring容器中@EnableAutoConfiguration注解中使用了@Import({AutoConfigurationImportSelector.class})注解,AutoConfigurationImportSelector实现了DeferredImportSelector接口,DeferredImportSelector接口继承了ImportSelector接口,ImportSelector接口只有一个selectImports方法。selectImports方法返回一组bean,@EnableAutoConfiguration注解借助@Import注解将这组bean注入到spring容器中,springboot正式通过这种机制来完成bean的注入的。
参考文档:https://blog.51cto.com/14442094/2427783?source=dra