Spring中关于bean与IoC的解析

一、bean的概念

1.Spring官方文档对于bean的解释为:

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container.

翻译过来就是:在Spring中,形成你的应用程序的主干,并且被Spring IoC容器管理的对象叫做bean;一个bean就是被Spring IoC容器实例化、装配并且管理的对象。

2.从官网文档我们可以知道:

  • bean是被Spring IoC容器管理的一个对象
  • bean能够被Spring IoC容器实例化并装配

二、Spring IoC的概念

1.IoC:Invention of Control;控制反转;也叫做DI:Dependency Injection:依赖注入

2.为什么出现IoC的概念?

  • 对于软件工程而言,可能需要多个系统之间、多个模块之间、多个对象之间的相互耦合,共同组成一个企业级应用工程,随着耦合度越来越高,极容易牵一发而动全身的情况,只要其中一小部分出现问题,整个工程便无法实现功能。为了解决这种系统、模块、对象之间的耦合度过高的问题,提出了IoC的概念。如今IoC的理论在Spring中得到充分的展现。
  • IoC其实就相当于一个第三方中间件,对象之间都根据这个第三方形成依赖关系。
  • 这种体系的好处在于:之前对象之间组成依赖关系,若其中一个对象出现问题,则全局无法开展;而使用一个第三方中间件之后,尽管其中一个对象出现问题,其他模块都能够正常工作。
  • 因此,可以将IoC容器看作是所有对象之间的粘合剂,这些对象的控制权都交给了IoC,这样就叫做控制反转。
  • 举个例子,若对象A与对象B存在依赖关系,引入IoC后,控制权交给了IoC;当A需要B时,不需要主动与对象B进行交互,而直接让IoC创建一个对象注入到A所需要B的位置。A获取B的方式由主动创建转为被动接受注入。这,就是IoC。同时也引出了IoC的同义名词-依赖注入。

对Spring IoC更系统的讲解请参考:https://www.cnblogs.com/superjt/p/4311577.html

三、bean的实例化、装配、管理

1.bean的创建

    * bean:配置一个bean对象,将对象交给IOC容器管理

    * 包含的属性:

        * id:bean的唯一标识,不能重复

        * class:设置bean对象所对应的类型(只能为类,不能为接口)

 <bean id="hellospring" class="com.gz.pojo.HelloWorld"></bean>

2.bean的获取

* 根据bean id 获取

* 根据bean 类型 获取(用得最多)

* 根据 bean id 和 类型 获取

@Test
public void testHelloWorld(){
//1.获取IOC容器:使用ApplicationContext的子类:ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取IOC容器中的bean对象:使用getBean()方法
//获取bean对象的三种方式
//1.根据bean的 ID 获取
HelloWorld bean1 = (HelloWorld) ioc.getBean("hellospring");
//2.根据bean的 类型 获取
HelloWorld bean2 = ioc.getBean(HelloWorld.class);
//3.根据bean的 ID + 类型 获取
HelloWorld bean3 = ioc.getBean("hellospring", HelloWorld.class);
bean1.sayHello();
bean2.sayHello();
bean3.sayHello();
}

3.获取bean常见问题

        1. bean中class类不提供无参构造器时因反射失败而报错

        2. 根据bean 类型 获取时,要求IOC容器中一定要有一个、并且有且只有一个类型匹配的bean。若bean中出现两个id不同但相同class,会报错

        3. 如果组件类实现了接口,能根据接口类型获取bean吗?

            * 可以;前提bean是唯一的

        4. 如果一个接口有多个实现类,这些实现类都配置了bean,根据接口类型能获取bean吗?

            * 不能,因为bean不唯一

        5. 总结:根据类型获取bean时,在满足bean唯一性的前提下,只看:对象 instanceof  指定的类型的返回结果,只要返回的事true就可以认定为和类型匹配,能够获取到(由于是面向接口编程,很多时候都是通过接口类型获取bean的)

            * 即:通过bean的类型、bean所继承的类的类型、bean所实现的接口的类型都可以获取bean
 

4.bean的作用域

* 在Spring中可以通过配置bean标签的scope属性指定bean的作用域范围

    * singleton(默认):在iooc容器中,bean的对象始终为单实例(用得多)

   <bean id="studentTest" class="com.gz.spring.pojo.Student" scope="singleton">

    * prototype:bean在ioc容器中有多个实例

   <bean id="studentTest" class="com.gz.spring.pojo.Student" scope="prototype">

* 若在WebApplicationContezr环境下还会有另外两个作用域(不常用)

    * request:在一个请求范围内有效

    * session:在一个会话范围内有效

5.bean的生命周期

* 第一步:实例化

    * 通过反射/工厂模式

* 第二步:依赖注入:即为属性赋值

* 第三步:初始化:需要自定义init_method

* 第四步:销毁:需要自定义destroy_method

    * 要想销毁,需要使用configurable ApplicationContext才能调用close

    * configurableApplicationContext是ApplicationContext的子接口,其中扩展了刷新和关闭容器的方法

    //3.生命周期第三步:初始化
    public void initMethod(){
        System.out.println("生命周期第三步:初始化");
    }

    //4.销毁
    public void destroyMethod(){
        System.out.println("生命周期第四步:销毁");
    }
 <bean id="user" class="com.gz.spring.pojo.User" 
init-method="initMethod" destroy-method="destroyMethod" 
scope="singleton">
        <property name="id" value="1"></property>
        <property name="username" value="admin"></property>
        <property name="password" value="0111"></property>
        <property name="age" value="11"></property>
 </bean>

* 补充:在生命周期初始化前后,后置处理器会添加额外的操作;此时在ioc容器中配置后,会对每一个bean起作用(了解)

6.不同作用域对生命周期的影响(从生命周期的角度理解)

* 若bean作用域为单例,则生命周期的前三步:实例化、依赖注入、初始化,会在获取ioc容器时执行

* 若bean作用域为多例,则生命周期的前三步会在获取bean时执行

总结

        总而言之,关于bean这个概念就如本文第一部分所讲,是一个被Spring IoC容器管理的对象,是组成应用程序的主干;但这样理解毕竟比较抽象,要想对这一个概念有足够清晰的认识,需要多思考、多灵活运用。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值