我们今天主要学习IOC容器中Bean的其他使用细节,主要学习以下三方面:
了解即可,默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了,即使用
@Autowired
根据name获取bean
Object getBean(String name)
根据类型获取bean
<T> T getBean(Class<T> requiredType)
根据name获取bean(带类型转换)
<T> T getBean(String name, Class<T> requiredType)
使用示例:
@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);
}
}
在springboot中,有springboot自动创建了bean对象默认是
单例模式
,即共用一个bean对象,如果不行共用同一个bean对象,这就涉及到了bean对象的作用域问题
作用域 | 说明 |
---|---|
singleton | 容器内同名称的bean只有一个实例(单例)(默认) |
prototype | 每次使用该bean时会创建新的实例(非单例) |
request | 每个请求范围内会创建新的实例(web环境中,了解) |
session | 每个会话范围内会创建新的实例(web环境中,了解) |
application | 每个应用范围内会创建新的实例(web环境中,了解) |
在实际开发中,绝大多数的bean是不需要配置scope属性的,@Lazy了解即可,没看出有什么作用,只不过是初始化迟了一些,但还是单例模式
<dependency>
<groupId>org.dom4jgroupId>
<artifactId>dom4jartifactId>
<version>2.1.3version>
dependency>
以前,如果我们想将一个类交给IOC容器管理,只需要在类上加上@Component以及它的这三个衍生注解(@Controller、@Service、@Repository),就可以来声明这个bean对象,但是第三方bean无法修改,只有只读权限,就只能另寻他法了。
解决方案1:在启动类上添加@Bean标识的方法(不推荐,我们当尽量保持启动类的干净)
@SpringBootApplication
public class SpringbootWebConfig2Application {
public static void main(String[] args) {
SpringApplication.run(SpringbootWebConfig2Application.class, args);
}
//声明第三方bean
@Bean //将当前方法的返回值对象交给IOC容器管理, 成为IOC容器bean
public SAXReader saxReader(){
return new SAXReader();
}
}
解决方案2:在配置类中定义@Bean标识的方法
配置类
,记住,配置类后面springboot原理篇会考!!!@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();
}
}
在方法上加上一个@Bean注解,Spring 容器在启动的时候,它会自动的调用这个方法,并将方法的返回值声明为Spring容器当中的Bean对象。如果第三方bean需要依赖其它bean对象,
直接在bean定义方法中设置形参
即可,容器会根据类型自动装配。即这里的这里的SAXReader对象创建时通过依赖注入了DeptService
测试类:
@SpringBootTest
class SpringbootWebConfig2ApplicationTests {
@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 + " : " + age);
}
//省略其他代码...
}
注意事项 :
- 通过@Bean注解的name或value属性可以声明bean的名称,如果不指定,默认bean的名称就是方法名。