1.什么是IOC
(1)控制反转,把对象创建和对象之间的调用过程,交给 Spring 进行管理
(2)使用 IOC 目的:为了耦合度降低
为什么IOC可以极大的降低耦合度?
(1)原始版:一般我们想使用userDao中的方法时,会在调用地创建userDao的对象,当userDao对象包名更改或者方法名更改时,也同时要修改userService中的代码,耦合度很高!
(2)进阶版,使用工厂模式生成userDao对象,解决了service和dao的耦合,但是dao和factory又耦合
(3)最终版 IOC
2.IOC底层原理
由上图可知ioc的底层技术其实就是 xml 解析、工厂模式、反射
IOC容器的底层就是对象工厂(类似于上边的factory) beanFactory
Spring 提供 IOC 容器实现两种方式:(两个接口)
(1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用
加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象(类似于懒加载)
(2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人
员进行使用
加载配置文件时候就会把在配置文件对象进行创建
为什么开发时多使用ApplicationContext?
当前应用大部分是web应用,在请求时如果还要创建对象 将非常耗时,所以在容器启动时,你可多耗费一点时间把所有对象创造完成,减少请求时间,提高访问速度。
3.spring容器管理的bean类型
Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)
2、普通 bean:在配置文件中定义 bean 类型就是返回类型
3、工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样(主要用于自定义一些具有复杂逻辑的bean对象)
//第一步 创建类,让这个类作为工厂 bean,实现接口 FactoryBean
public class MyBean implements FactoryBean<Course> {
//定义返回 bean
@Override
public Course getObject() throws Exception {
Course course = new Course();
course.setCname("abc");
return course;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
//第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
<bean id = "myBean" class="com.atguigu.spring5.factorybean.MyBean" ></bean >
@Test
public void test3 () {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean3.xml");
Course course = context.getBean("myBean", Course.class); //返回类型并不是MyBean,和普通bean不一样的
System.out.println(course);
}
4.bean的生命周期
一共七步:
(1)通过构造器创建 bean 实例(无参数构造)
(2)bean的属性赋值(调用 set 方法)
(3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
注意:
postProcessBeforeInitialization方法会在每个bean的初始化之前被调用一次; 如果当前的bean实现了某个xxxWare接口,那么它的某个对应的方法就会被调用,例如我们创建了一个bean实现了ApplicationContextAware接口,那么这个bean的setApplicationContext方法就会被调用,入参是applicationContext成员变量,这样我们的bean就能得到applicationContext对象了;
展开上图中标红的方法即可看到
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
//检查bean属于哪个Aware
//如果属于,就根据规则配置进容器里
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)