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 {
@Autowiredprivate DeptService deptService;
public DeptController(){System.out.println("DeptController constructor ....");}
@GetMappingpublic 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();}
@PostMappingpublic Result save(@RequestBody Dept dept){deptService.save(dept);return Result.success();}
}
业务实现类:DeptServiceImpl@Slf4j
@Service
public class DeptServiceImpl implements DeptService {@Autowiredprivate DeptMapper deptMapper;
@Overridepublic List<Dept> list() {List<Dept> deptList = deptMapper.list();return deptList;}
@Overridepublic void delete(Integer id) {deptMapper.delete(id);}
@Overridepublic 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 {
@Autowiredprivate ApplicationContext applicationContext; //IOC容器对象
//获取bean对象@Testpublic 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而言。