spring的IOC原理,容器管理的bean类型、bean的生命周期

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 的销毁的方法(需要进行配置销毁的方法)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值