以前,小白在写代码的工作中,想用service类的时候一直用@Autowird或者@Resource这两个方法来注入进行使用,有一天老大说你有没有想过为什么这样就能注入service?,小白说因为我在服务类上加了@Service,老大说你这只是看到了表象。你去看看spring容器,然后小白就写了一篇文章记录自己的学习过程。
小白思考第一问:spring容器是什么?
小白就去百度查询了这个问题:
Spring 容器是 Spring 框架的核心,是用来管理对象的。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。
从具象化讲:通过概念的描述有些同学还是一脸懵逼,在我们的项目中哪个东西是Spring容器?在java项目中,我们使用实现了org.springframework.context.ApplicationContext接口的实现类。在web项目中,我们使用spring.xml——Spring的配置文件。
从代码上讲:一个Spring容器就是某个实现了ApplicationContext接口的类的实例。也就是说,从代码层面,Spring容器其实就是一个ApplicationContext(一个实例化对象)。
---------------------
版权声明:本文为优快云博主「_Mast」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/qq_34598667/article/details/83245753
看了这个博主的解答,小白细细品味了一番,自己也给出了理解:spring容器可以实例化对象。
小白第二问:怎么用spring容器实例化对象?
小白听了热血沸腾,原来还能这样来获得实例,马上开始打开idea开始写测试用例。小白写了个Service和test测试类,我偷偷去复制粘贴给大家看一下。
@Service
public class AddService {
public int add(int a,int b){
return a+b;
}
}
我偷偷把原来小白怎么用的方式粘贴一下,这么用是完全没有问题的
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SsoApplication.class)
public class AddServiceTest {
@Autowired
private AddService addService2;
@Test
public void add() throws Exception {
addService2.add(1,2);
}
}
小白想了想还是有地方不明白,从容器中通过什么来获取实例。正在小白百思不得其姐的时候,老大刚好看到并顺便提醒小白,想想自动注入的时候什么是一直不变的,小白顺着老大给的提示去网上找了找,原来是通过类名去获取bean实例。
解答2:看看怎么从spring容器中获得实例
这是小白想明白之后写的代码,我们一起看一下。(有人很好奇,我是谁,我是解说员啊!!!解说小白菜鸟的一生)
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SsoApplication.class)
public class AddServiceTest {
private static ApplicationContext applicationContext;
@Test
public void add() throws Exception {
//去spring容器中获取对象
AddService addService = (AddService) applicationContext.getBean("addService");
System.out.println(addService.add(1,3));
System.out.println(addService.getClass());
}
}
小白很激动的开始运行,然我们来看看结果
小白看到空指针,心里热血沸腾,踢开自己的牛,自己梗了二里地,然后冷静下来,小白用dubug模式发现是因为applicationContext是空的,这时候老大悄悄咪咪的站了出来,原来老大一直没走,默默的看小白操作。老大看到告诉小白:“小白呀小白,想想是不是spring容器在你用的时候没有初始化,我上次教过你用@Component将bean初始化,你想想怎么用?”,小白也是聪明,瞬间明白了老大的意思,然后写了个工具类,然后对测试用例做了些许调整又开始测试。然我们看一下工具类
@Component
public class SpringUtils implements BeanFactoryAware, ApplicationContextAware {
private static Logger log = LoggerFactory.getLogger(SpringUtils.class);
private static BeanFactory beanFactory;
private static ApplicationContext applicationContext;
/**
* 通过bean的id从上下文中拿出该对象
*/
public static Object getBean(String beanId) {
return beanFactory == null ? applicationContext.getBean(beanId) : beanFactory.getBean(beanId);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SsoApplication.class)
public class AddServiceTest {
@Test
public void add() throws Exception {
//去spring容器中获取对象
AddService addService = (AddService) SpringUtils.getBean("addService");
System.out.println(addService.add(1,3));
System.out.println(addService.getClass());
}
小白很激动的点了运行,我们来看看运行结果
“哇,居然真的可以耶”,小白激动的又去梗了二里地。
至此,spring容器我们就简单的介绍至此,小白用的是springboot1.5.9的版本。
然后老大提出几个问题让小白私下思考:什么方式可以将bean放到spring容器中?spring容器能存放哪些东西?小白今天梗了几里地?
补充一下:SpringUtils还得继承两个接口,实现里面两个方法;
好了,今天小白的学习到此告一段落,大家想对小白有更多的了解,请关注我。也可以将老大提的几个问题在评论区讨论。