目录
SpringBoot原理
内容偏向于底层的原理分析
基于Spring框架进行项目的开发有两个不足的地方:
SpringBoot 框架底层提供了两个非常重要的功能:一个是起步依赖,一个是自动配置。
起步依赖
起步依赖的原理就是Maven的依赖传递。
如果使用了SpringBoot,就不需要繁琐的引入依赖了。只需要引入一个依赖就可以了,那就是web开发的起步依赖:springboot-starter-web。
自动配置
SpringBoot的自动配置就是当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中, 不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。
在CommonConfig配置类上添加了一个注解@Configuration,而@Configuration底层就是@Component,所以配置类CommonConfig最终也是SpringIOC容器当中的一个bean对象
方案一:
@SpringBootApplication
@ComponentScan({"com.itheima","com.example"}) //指定要扫描的包
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
进行项目开发时,当需要引入大量的第三方的依赖,就需要在启动类上配置N多要扫描的包,这种方式会很繁琐。而且这种大面积的扫描性能也比较低。
不推荐使用
方案二
@Import 导入
1.导入普通类
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
2.导入配置类
@Configuration
public class HeaderConfig {//配置类
@Bean
public HeaderParser headerParser(){
return new HeaderParser();
}
@Bean
public HeaderGenerator headerGenerator(){
return new HeaderGenerator();
}
}
@Import(HeaderConfig.class) //导入配置类
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
3.接口实现类
public class MyImportSelector implements ImportSelector {//接口实现类
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//返回值字符串数组(数组中封装了全限定名称的类)
return new String[]{"com.example.HeaderConfig"};
}
}
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
结论:我们不用自己指定要导入哪些bean对象和配置类了,让第三方依赖它自己来指定。
4.使用第三方依赖提供的 @EnableXxxxx注解(SpringBoot当中所采用的方式)
第三方依赖中提供的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(MyImportSelector.class)//指定要导入哪些bean对象或配置类
public @interface EnableHeaderConfig {
}
在使用时只需在启动类上加上 @EnableXxxxx 注解即可
@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
}
配置优先级
SpringBoot 项目当中支持的三类配置文件:
- application.properties
- application.yml
- application.yaml
配置文件优先级排名(从高到低):
在SpringBoot项目当中除了以上3种配置文件外,SpringBoot为了增强程序的扩展性,除了支持配置文件的配置方式以外,还支持另外两种常见的配置方式:
1. Java系统属性配置 (格式: -Dkey=value)
2. 命令行参数 (格式:--key=value)
优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数
项目打包
点击右侧Maven中的package进行打包
显示打包完成
找到jar包的文件目录:
在当前目录下输入cmd回车,即可在当前目录下打开命令行
通过指令
- java -Dserver.port=9000 -jar tlias-0.0.1-SNAPSHOT.jar
- java -jar tlias-0.0.1-SNAPSHOT.jar --server.port=9000
- java -Dserver.port=9000 -jar tlias-0.0.1-SNAPSHOT.jar --server.port=10010
以上三种方式可更改端口号,第三种端口号改为10010,因为命令行参数优先级高于java系统属性
通过ctrl c可结束操作
优先级顺序,从高到低:
Bean设置
通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象,为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI。
获取Bean
默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过 程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对 象,就直接进行依赖注入就可以了。
在Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:
1. 根据name获取bean
2. 根据类型获取bean
3. 根据name获取bean(带类型转换)
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {
@Autowired
private ApplicationContext applicationContext; //IOC容器对象
//获取bean对象
@Test
public void testGetBean(){
//根据bean的名称获取
DeptController bean1 = (DeptController)
applicationContext.getBean("deptController");
System.out.println(bean1);
//根据bean的类型获取
DeptController bean2 = applicationContext.getBean(DeptController.class);
System.out.println(bean2);
//根据bean的名称 及 类型获取
DeptController bean3 = applicationContext.getBean("deptController",
DeptController.class);
System.out.println(bean3);
}
}
默认bean对象是单例模式(只有一个实例对象)。那么如何设置bean对象为非单例呢?需要设置bean的作用域。
作用域 | 说明 |
singleton |
容器内同名称的 bean 只有一个实例(单例)(默认) |
prototype |
每次使用该 bean 时会创建新的实例(非单例) |
request |
每个请求范围内会创建新的实例( web 环境中,了解) |
session |
每个会话范围内会创建新的实例( web 环境中,了解) |
application |
每个应用范围内会创建新的实例( web 环境中,了解) |
借助Spring中的@Scope注解来配置Bean的作用域
测试一
默认bean的作用域为:singleton (单例)
@Lazy //延迟加载(第一次使用bean对象时,才会创建bean对象并交给ioc容器管理)
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}
测试二
@Scope("prototype") //bean作用域为非单例
@Lazy //延迟加载
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
//省略其他代码...
}
第三方Bean
要从IOC容器当中来获取到bean对象,需要先拿到IOC容器对象,怎么样才能拿到IOC容器呢?
想获取到IOC容器,直接将IOC容器对象注入进来就可以了
在配置类中定义@Bean标识的方法
如果需要定义第三方Bean时, 通常会单独定义一个配置类
@Configuration //配置类 (在配置类当中对第三方bean进行集中的配置管理)
public class CommonConfig {
//声明第三方bean
@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
//通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名
public SAXReader reader(DeptService deptService){
System.out.println(deptService);
return new SAXReader();
}
}
如果是在项目当中我们自己定义的类,想将这些类交给IOC容器管理,我们直接使用@Component 以及它的衍生注解来声明就可以。
如果这个类它不是我们自己定义的,而是引入的第三方依赖当中提供的类,而且我们还想将这个类 交给IOC容器管理。此时我们就需要在配置类中定义一个方法,在方法上加上一个@Bean注解,通过这种方式来声明第三方的bean对象。
注解:8--SpringBoot原理分析、注解-详解(面试高频提问点)-CSDN博客