依赖管理
每个springboot的父项目都是spring-boot-starter-parent
spring-boot-starter-parent的父项目是spring-boot-dependencies,
在其中声明了基本上所有要用到的依赖对应的版本(和创建的springboot工程相对应)
所以我们依赖不用写版本号,因为有默认的版本号。
如果要使用自己定义的版本号,可以在propertie里定义版本号
<properties> <mysql.version>5.1.43</mysql.version> </properties>
spring-boot-starter场景启动器,包括了这个功能所需的所有依赖,不需要一个个导入,只需要一个启动器就可以。
spring-boot-autoconfigure依赖里有所有的场景,
当引入了对应的starter启动器,配置就会生效。
导入组件的方式
1.@Configuration配置类
@Bean
@Configuration默认参数proxyBeanMethods=true表示单实例,改为false则不是单实例
2. @Component
@Service
@Controlller
@Repository
3.@Import这个注解必须写在已经导入容器的组件上
数组,可以一次性导入多个组件,调用组件的无参构造器创建对象放入容器
4.@Conditional根注解下有很多条件装配的注解(双击shift搜索@Conditional,ctrl+h打开继承树)
例如
@ConditionalOnBean(name="xxx"或者xxx.class)表示当容器中存在xxx实例时才将该注解下的对象注入容器
5.@ImportResource("classpath:beans.xml")
有一些用bean.xml配置的bean可以用这种方式导入
自动配置原理
@SpringBootApplication 是启动类,(必须和controller这些包同级)
原因:
这个注解实际上是@SpringBootConfiguration
@EnableAutoConfiguration 自动配置
@ComponentScan("")由这三个注解组成,第三个默认扫描启动类的上一级,所以启动类必须和controller这些包同级。
@EnableAutoConfiguration
@AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class})
1.点开@AutoConfigurationPackage里导入了下面这个组件
@Import(AutoConfigurationPackages.Registrar.class)
点开Register,下面这行代码可以得到启动类所在目录的包名,可以用debug调试。
register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
所以@AutoConfigurationPackage目的是得到默认的包名
2. @Import({AutoConfigurationImportSelector.class})
点开AutoConfigurationImportSelector,selectImports方法下的
getAutoConfigurationEntry(annotationMetadata);这行
作用是所有组件批量导入容器
可以debug调试发现一步步下去会得到所有的配置类。
其中的getCandidateConfigurations()方法点进去,到
通过spring工厂加载所有的配置类,点进SpringFactoriesLoader类,发现所有的配置类都来自
"META-INF/spring.factories",系统会去扫描这个文件,在spring-boot-autoConfigure的META-INF下的spring.factories有所有的自动配置类。
在spring.factories里写明了这个@EnableAutoConfiguration下的所有自动配置类
按需加载配置
虽然启动的时候会加载全部的配置,最终会按需配置。
随便点进一个发现都是条件装配
@ConditionalOnClass(Advice.class),只有有这个类才会装配一些配置。
导入启动器的依赖,就会有这个类,就能实现自动装配。
自定义组件的方式
1.配置类里@Bean组件加入组件替换掉默认的组件
2.获知底层写的绑定properties里的参数前缀,在文件里修改参数