2. Bean管理
在前面的课程当中,我们已经讲过了我们可以通过Spring当中提供的注解@Component以及它的三个衍生注解(@Controller、@Service、@Repository)来声明IOC容器中的bean对象,同时我们也学习了如何为应用程序注入运行时所需要依赖的bean对象,也就是依赖注入DI。
我们今天主要学习IOC容器中Bean的其他使用细节,主要学习以下三方面:
- 如何从IOC容器中手动的获取到bean对象
- bean的作用域配置
- 管理第三方的bean对象
接下来我们先来学习第一方面,从IOC容器中获取bean对象。
2.1 获取Bean
默认情况下,SpringBoot项目在启动的时候会自动的创建IOC容器(也称为Spring容器),并且在启动的过程当中会自动的将bean对象都创建好,存放在IOC容器当中。应用程序在运行时需要依赖什么bean对象,就直接进行依赖注入就可以了。
而在Spring容器中提供了一些方法,可以主动从IOC容器中获取到bean对象,下面介绍3种常用方式:
- 根据name获取bean
Object getBean(String name)
- 根据类型获取bean
<T> T getBean(Class<T> requiredType)
- 根据name获取bean(带类型转换)
<T> T getBean(String name, Class<T> requiredType)
思考:要从IOC容器当中来获取到bean对象,需要先拿到IOC容器对象,怎么样才能拿到IOC容器呢?
- 想获取到IOC容器,直接将IOC容器对象注入进来就可以了
控制器:DeptController
@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); } @DeleteMapping("/{id}") public Result delete(@PathVariable Integer id) { deptService.delete(id); return Result.success(); } @PostMapping public Result save(@RequestBody Dept dept){ deptService.save(dept); return Result.success(); } } 业务实现类:DeptServiceImpl @Slf4j @Service public class DeptServiceImpl implements DeptService { @Autowired private DeptMapper deptMapper; @Override public List<Dept> list() { List<Dept> deptList = deptMapper.list(); return deptList; } @Override public void delete(Integer id) { deptMapper.delete(id); } @Override public void save(Dept dept) { dept.setCreateTime(LocalDateTime.now()); dept.setUpdateTime(LocalDateTime.now()); deptMapper.save(dept); } }
Mapper接口:
@Mapper public interface DeptMapper { //查询全部部门数据 @Select("select * from dept") List<Dept> list(); //删除部门 @Delete("delete from dept where id = #{id}") void delete(Integer id); //新增部门 @Insert("insert into dept(name, create_time, update_time) values (#{name},#{createTime},#{updateTime})") void save(Dept dept); }
测试类:
@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对象地址值是一样的,说明IOC容器当中的bean对象有几个?
答案:只有一个。 (默认情况下,IOC中的bean对象是单例)
那么能不能将bean对象设置为非单例的(每次获取的bean都是一个新对象)?
可以,在下一个知识点(bean作用域)中讲解。
注意事项:
- 上述所说的 【Spring项目启动时,会把其中的bean都创建好】还会受到作用域及延迟初始化影响,这里主要针对于默认的单例非延迟加载的bean而言。