IOC的提出
在传统的javaweb中,程序员自己定义的pojo对象之后还得要自己进行创建有许多的类都耦合到一起去了。假如咱编写bean的时候脑子不清晰,写错了逻辑又没反应过来后面继续使用这个bean就会引起连锁反应,大家一起完蛋。所以在Spring中便提出了IOC(控制反转)原来创建bean实例的活都交给了Spring容器去做,我们在需要使用的时候只需从容器中取出即可,非常的人性化。
注入之前的准备
- 创建bean文件夹
首先在com.cdd的目录下创建一个pojo文件夹
之后的bean都是创建在这个pojo文件夹里的(虽然之前web学过)
然后创建一个bean对象如下
public class Message1 {
String msg;
public Message1(String msg) {
this.msg = msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void show() {
System.out.println(this.msg + "欢迎来到Spring");
}
}
- 创建相关的xml文件
然后就需要在resource下创建一个xml文件来创建bean拉,首先需要写出以下内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--这里写bean标签-->
<bean id="msg" class="com.cdd.pojo.Message1">
<constructor-arg name="msg" value="123"></constructor-arg>
<property name="msg" value="hello"></property>
</bean>
</beans>
现在已经给标签标
- 使用容器
这里咱可以使用applicationContext接口或者是beanFactory接口来创建一个工厂并用他们来构建bean对象,这边先使用applicationContext吧。代码如下
// 加载相关的配置
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取相关信息
Object msg = applicationContext.getBean("msg");
// 输出相关信息
System.out.println(msg);
最后系统会打印出这样一段虚拟化之后的地址
这样就成功通过一个Spring容器来构建了一个bean实例对象,不用再让我们new一个了。但是或许哪里注入了呢?其实在编写xml的bean标签时便已经把信息狠狠的注入到对象里面了。还有一种beanFactory其实就是applicationContext的实现底层,它只是把beanFactory稍微进行了封装,并且相比于beanFactory还多出了些许的功能。接下来在使用beanFactory打印msg。
// 创建beanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 创建读取器
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
// 加载配置文件
reader.loadBeanDefinitions("applicationContext.xml");
// 获取对象并输出
Object msg1 = factory.getBean("msg");
System.out.println(msg1);
最终也打印出如上地址
beanFactory和ApplicationContext的关系
- beanFactory是Spring的早期接口成为bean工厂,另一个是之后实现的更高级的接口称之为Spring容器
- applicationContext在底层还是维持对beanFactory的引用,并且除此之外还有监听等功能
- applicationContext不仅维持对beanFactory的继承,还和它存在这融合关系
- Bean的初始化时机不同,beanFactory在要调用的时候才创建bean,而applicationContext在刚刚开始就已经初始化完毕了
bean对象在底层是如何进行创建的
我们配置下xml文件中的信息再get一下bean就得到了一个bean对象,但是这中间Spring容器时如何进行创建的?
在Spring中存在一个BeanDefinition 类,它是把咱们的xml配置文件中的bean标签里的信息封装成为一个对象,不是把bean标签里的bean封装为对象,而是封装bean标签里我们设置的那些信息(如: scope之类的),然后把这些封装完毕的对象存储到beanDefinitionMap的Map集合中,源码如下:
private final Map<String, BeanDefinition> beanDefinitionMap;
String便是name,接着再通过java的反射技术把这些对象实例化成我们想要的Bean实例对象,最终通过getBean返回我们想要的实例对象。