一、bean管理
Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象。如何为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI。
默认情况下,Spring项目启动时,会把bean都创建好放在IOC容器中。如果要获取到容器对象,可以通过如下方式:
1.1 bean的获取:
根据name获取bean:Object getBean(String name)。
根据类型获取bean: T getBean(Class requiredType)。
根据name获取bean(带类型转换): T getBean(String name, Class requiredType)。
java
@SpringBootTest
public class SpringbootApplicationTests {
//获取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);
}
运行结果:

1.2 bean的作用域配置
在Spring中支持五种作用域,后三种在web环境才生效:
| 作用域 | 说明 |
|---|---|
| singleton | 容器内同名称的bean只有一个实例(单例)(默认) |
| prototype | 每次使用该bean时会创建新的实例(非单例) |
| request | 每个请求范围内会创建新的实例(web环境中) |
| session | 每个会话范围内会创建新的实例(web环境中) |
| application | 每个应用范围内会创建新的实例(web环境中) |
bash
@Scope("prototype")
@Lazy
@RestController
@RequestMapping("/depts")
public class DeptController {
@Autowired
private DeptService deptService;
public DeptController(){
System.out.println("DeptController constructor ....");
}
@GetMapping
public Result list(){
List<Dept> deptList = deptService.list();
return Result.success(deptList);
}
运行如下:

默认singleton的bean,在容器启动时被创建,可以使用@Lazy注解来延迟初始化(延迟到第一次使用时)。
prototype的bean,每一次使用该bean的时候都会创建一个新的实例。
开发当中,绝大部分的Bean是单例的,也就是说绝大部分Bean不需要配置scope属性。
解决循环依赖:
方式一:
添加@Lazy注解。
java
public class ServiceA {
@Lazy
@Autowired
private ServiceB serviceB;
方式二:
设置allow-circular-references属性为true。
yaml
spring:
#数据库连接信息
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db01
username: root
password: 123456
main:
# 解决循环依赖问题
allow-circular-references: true
1.3 管理第三方的bean对象
如果要管理的bean对象来自于第三方(不是自定义的),是无法用 @Component 及衍生注解声明bean的,就需要用到 @Bean注解。
若要管理的第三方bean对象,建议对这些bean进行集中分类配置,可以通过@Configuration注解声明一个配置类。
使用dom4j读取XML文件:
方式一(不推荐):
java
@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
public SAXReader saxReader(){
return new SAXReader();
}
方式二:
java
@Slf4j
@Configuration //配置类
public class CommonConfig {
//声明第三方bean
@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
//通过@Bean注解的name/value属性指定bean名称, 如果未指定, 默认是方法名
public SAXReader reader(DeptService deptService){
log.info("创建saxReader对象...");
System.out.println(deptService);
return new SAXReader();
}
}
Bean注入IOC容器:

测试:
java
@Autowired
private SAXReader saxReader;
//第三方bean的管理
@Test
public void testThirdBean() throws Exception {
Document document = saxReader.read(this.getClass().getClassLoader().getResource("1.xml"));
Element rootElement = document.getRootElement();
String name = rootElement.element("name").getText();
String age = rootElement.element("age").getText();
System.out.println( "name : " + name);
System.out.println( "age : " + age);
}
测试如下:

Bean对象需要注入IOC容器,错误提示如下:

注意:
通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。
如果第三方bean需要依赖其它bean对象,直接在bean定义方法中设置形参即可,容器会根据类型自动装配。也可以使用@Autowired注入,
IOC容器中:名字不能重复。默认是类名小写,可以自定义;

java
//声明第三方bean
@Bean("SAXReader")
public SAXReader saxReader(DeptService deptService){
log.info("创建saxReader对象...");
System.out.println("创建saxReader对象..."+ deptService);
return new SAXReader();
}
二、SpringBoot原理
起步依赖:
起步依赖的原理是Maven的依赖传递。
自动配置:
SpringBoot的自动配置就是当spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。
引入依赖:
yml
<!-- 监控依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

自动配置实现方案:
- 方案1:@ComponentScan 组件扫描
java
@SpringBootApplication
@ComponentScan({"com.it","com.example"}) //指定要扫描的包
public class Springboot2Application {
public static void main(String[] args) {
SpringApplication.run(Springboot2Application.class, args);
}
}
- 方案2:@Import 导入(使用@Import导入的类会被Spring加载到IOC容器中)
导入形式主要有以下几种:
- 导入普通类。
- 导入配置类。
- 导入ImportSelector接口实现类。
1.导入普通类。
bash
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class Springboot2Application {
public static void main(String[] args) {
SpringApplication.run(Springboot2Application.class, args);
}
}
- 导入配置类。
配置类:
bash
@Configuration
public class HeaderConfig {
@Bean
public HeaderParser headerParser(){
return new HeaderParser();
}
@Bean
public HeaderGenerator headerGenerator(){
return new HeaderGenerator();
}
}
启动类:
bash
@Import(HeaderConfig.class) //导入配置类
@SpringBootApplication
public class Springboot2Application {
public static void main(String[] args) {
SpringApplication.run(Springboot2Application.class, args);
}
}
- 导入ImportSelector接口实现类。
ImportSelector接口实现类:
bash
public class MyImportSelector implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//返回值字符串数组(数组中封装了全限定名称的类)
return new String[]{"com.example.HeaderConfig"};
}
}
启动类:
bash
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class Springboot2Application {
public static void main(String[] args) {
SpringApplication.run(Springboot2Application.class, args);
}
}
三、springboot 配置
SpringBoot项目当中支持的三类配置文件:
- application.properties
- application.yml
- application.yaml
application.properties配置文件:
properties
server.port=8081
- application.yml配置文件:
yaml
server:
port: 8082
- application.yaml配置文件:
yaml
server:
port: 8083
运行如下:

虽然springboot支持多种格式配置文件,但是在项目开发时,推荐统一使用一种格式的配置。(yml是主流)
配置文件优先级排名(从高到低):
- properties配置文件
- yml配置文件
- yaml配置文件
在SpringBoot项目当中除了以上3种配置文件外,SpringBoot为了增强程序的扩展性,除了支持配置文件的配置方式以外,还支持另外两种常见的配置方式:
- Java系统属性配置 (格式: -Dkey=value)
yaml
-Dserver.port=9000
- 命令行参数 (格式:--key=value)
yaml
--server.port=10010
五种配置方式的优先级: 命令行参数 > 系统属性参数 > properties参数 > yml参数 > yaml参数。