Spring笔记(3):IOC容器
创始人
2024-05-29 08:35:42
0

1、IOC容器是什么?
IOC容器是Spring容器的重要组成部分,它具有依赖注入功能,负责实例化、定位、配置Bean对象,并建立对象之间依赖。
通过配置(Metadata),由Spring容器创建对象,这个配置是对应POJO对象类的属性进行注入,创建完毕后发送给ApplicationContext容器进行渲染。

在这里插入图片描述


2、两种Spring常见IOC容器

  • Spring BeanFactory容器:是一种最简单的容器,通过BeanFactory接口定义。

  • Spring Application容器:是一种企业级容器,通过ApplicationContext接口定义

因为ApplicationContext容器包括BeanFactory的功能,所以通常不使用BeanFactory。
BeanFactory优点也明显,数据吞吐量和速度是优秀的。


3、Spring BeanFactory容器
Spring有大量对BeanFactory接口的实现,其最常使用的是XmlBeanFactory类。
XmlBeanFactory——功能是读取XML文件的配置数据形成BeanFactory
我们从介绍上也能看出来,XmlBeanFactory的数据来源是XML配置,并且在声明它时需要加载XML文件。


User.java

public class User {private String uid;private String uname;public User() {}public User(String uid, String uname) {this.uid = uid;this.uname = uname;}public String getUid() {return uid;}public void setUid(String uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}@Overridepublic String toString() {return "User{" +"uid='" + uid + '\'' +", uname='" + uname + '\'' +'}';}
}

Main.java

public class Main {public static void main(String[] args) {XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));User user = (User) factory.getBean("user");System.out.println(user.toString());}
}

Beans.xml


bean-id: bean对象的唯一编号bean-name:bean对象的名称bean-class:bean注入对象property-name:注入对象属性名property-value:注入对象属性值

我们需要什么依赖呢?
pom.xml

	org.springframeworkspring-beans5.3.18org.springframeworkspring-core5.3.20

一定要注意版本兼容问题,会报异常哦~

输出结果

User{uid='123123', uname='这是我的名字'}

4、Spring ApplicationContext容器

  • Application Context是BeanFacctory的子接口,也称为Spring上下文。
  • 可以加载配置文件中定义的bean,在请求状态下分配bean对象。
  • 另外增加了企业所需要的功能,例如从属性文件中解析文本和传递事件给监听器。
  • 通过context.ApplicationContext 接口定义。

加载XML文件的三种方式

  • FileSystemXmlApplicationContext: 通过扫描XML文件绝对路径进行载入
  • ClassPathXmlApplicationContext: 通过扫描XML文件相对路径进行载入
  • XmlWebApplicationContext: 在一个web应用程序范围内加载XML文件

需要ApplicationContext依赖——Spring Context
pom.xml

        org.springframeworkspring-context5.3.18

要注意版本兼容问题

Main.java

public class Main {public static void main(String[] args) {ApplicationContext context = new FileSystemXmlApplicationContext("D:/JavaWebProgram/BeanDemo/src/main/resources/Beans.xml");User user = (User) context.getBean("user");System.out.println("绝对路径下的Bean:"+user.toString());context = new ClassPathXmlApplicationContext("Beans.xml");user = (User) context.getBean("user");System.out.println("相对路径下的Bean:"+user.toString());}
}

输出结果

绝对路径下的Bean:User{uid='123123', uname='这是我的名字'}
相对路径下的Bean:User{uid='123123', uname='这是我的名字'}

5、Spring Bean

5.1 Spring Bean定义

Bean对象是构成应用程序的单元,被Spring IOC容器管理。
Bean定义包含配置元数据


可以配置什么元数据?

  • Bean的创建
  • Bean的生命周期
  • Bean的依赖关系

Bean的属性

属性描述
class这个属性是强制性的,并且指定用来创建 bean 的 bean 类。
name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。
scope这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。
constructor-arg它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
properties它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
autowiring mode它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。
initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。
destruction 方法当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。

Bean与Spring容器的关系

  • 步骤1: 扫描XML,扫描注解,配置类获取元数据
  • 步骤2: Spring容器定义注册表
  • 步骤3: Bean实现类实例化Bean对象,并装载入缓存池中
  • 步骤4: 应用程序调取缓存池中的Bean对象
    在这里插入图片描述

Spring配置元数据

有哪些方法可以配置元数据给Spring容器

  • 基于XML的配置文件(
  • 基于注解的配置(@Autowire)
  • 基于Java的配置(@Configuration)

5.2 Spring Bean 作用域


scope有哪些作用域值呢?

  • singleton: Bean以单例模式存在,即getBean时,是同一个Bean对象
  • prototype: Bean以原型模式存在,即getBean时,是不同的Bean对象
  • request: 每次HTTP请求创建新的Bean,仅适用于WebApplicationContext环境
  • session: 同一个Session会话共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境
  • global-session: 应用于Portlet应用环境,仅适用于WebApplicationContext环境

什么是Portlet?
它是一种基于Java的web组件化网页,看起来有点复古,支持Servlet进行HTTP的请求反馈。


singleton 作用域
singleton是默认作用域,如果你不指定scope,就只有一个Bean对象给你蹂躏。
singleton的创建时间是与容器一同被创建。

Main.java

public class Main {public static void main(String[] args) {ApplicationContext context;User user1,user2;context = new ClassPathXmlApplicationContext("Beans.xml");user1 = (User) context.getBean("user");System.out.println("user1:"+user1);user1.setUname("真差劲诶");user2 = (User) context.getBean("user");System.out.println("user2:"+ user2);}
}

输出结果

user1:User{uid='123123', uname='这是我的名字'}
user2:User{uid='123123', uname='真差劲诶'}

我们可以看到,在user1的set方法后,获取到的user2就是set后的数据,即这个bean是同一个对象。

prototype 作用域

prototype是一个原型模式下作用域,能够对应多实例,可以类比父类,getBean出来的则是一个它的子类,每一次get都是不同的子类。



我们在刚刚的程序文件上,只改动scope的值
输出结果

user1:User{uid='123123', uname='这是我的名字'}
user2:User{uid='123123', uname='这是我的名字'}

我们可以清晰的知道,它们是两个不同的对象,所以才不会受到user1对象的set方法影响。

5.3 Spring Bean 生命周期

  • Bean的定义
  • Bean的初始化
  • Bean的使用
  • Bean的销毁

两种重要生命周期

	init-method:调取初始化方法destroy-method:调取销毁方法

初始化回调与销毁回调

InitalizingBean接口实现初始化回调方法
DestroyBean接口实现销毁回调方法

User.java

package org.example.POJO;import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;/*** 包名:BeanDemo* 作者:章恩光* 时间:2023/3/5 22:09 周日*/
public class User implements InitializingBean, DisposableBean {private String uid;private String uname;public User() {}public User(String uid, String uname) {this.uid = uid;this.uname = uname;}public String getUid() {return uid;}public void setUid(String uid) {this.uid = uid;}public String getUname() {return uname;}public void setUname(String uname) {this.uname = uname;}public void init(){System.out.println("Bean is going through init");}public void destroy(){System.out.println("Bean will destroy now");}@Overridepublic String toString() {return "User{" +"uid='" + uid + '\'' +", uname='" + uname + '\'' +'}';}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("UserBean has created。");}
}

Beans.xml

	

Spring容器执行顺序:

  • 步骤1: 注入对象实现InitializingBean, DisposableBean接口,需要编写的方法有init(),destroy(),afterPrepartiesSet()
  • 步骤2:

提供默认初始化和销毁方法



5.4 Spring Bean 后置处理器

  • 什么是Bean 后置处理器? Bean的拓展坞,在初始化前后进行处理

  • 怎么实现后置处理器? BeanPostProcessor接口定义回调方法

    • 可以用该方法进行优化Spring容器启动效率,例如编写自己的实例化逻辑,依赖解析逻辑;
    • 可以在Spring容器中插入若干个BeanPostProcessor实现实例化,配置和初始化一个bean之后实现自定义逻辑回调方法;
    • 可以配置多个BeanPostProcessor接口,通过设置BeanPostProcessor.Ordered接口提供的order属性来控制BeanPostProcessor顺序。

注意:

  • Application自动检测后置处理器实现的bean,再通过容器创建bean。
  • 自定义接口实现类中,必须实现的方法:
    • BeanPostProcessor.postProcessBeforeInitialization(Object, String)​ ​
    • BeanPostProcessor.postProcessAfterInitialization(Object, String)

初始化类InitUser.java

public class InitUser implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("AfterInitialization:"+beanName);return bean;}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeforeInitialization:"+beanName);return bean;}
}

Beans.xml


加载初始化后置处理器

输出结果

BeforeInitialization:user
UserBean has created。
Bean is going through init
AfterInitialization:user
username:这是我的名字

执行过程顺序:

  • 后置器BeforeInitialization执行
  • Bean注册表创建
  • Bean执行init()方法
  • 后置器AfterInitialization执行
  • 使用Bean
  • Bean执行destroy()方法

5.5 Spring Bean 定义继承

bean定义可以包含很多配置信息:包括构造函数参数属性值初始化方法静态工厂方法名等等

继承bean可以重写值,或添加值。

它们之间的关系:与抽象类继承类的关系相同。



Bean 定义模板



相关内容

热门资讯

55英寸安卓系统,畅享科技与娱... 你有没有想过,家里的电视该升级换代了?别急,今天就来给你好好聊聊55英寸安卓系统的电视,看看它到底有...
全民k系统安卓版下载,一键下载... 你有没有听说最近超级火的全民K系统安卓版下载?没错,就是那个让无数手机用户为之疯狂的系统!今天,我就...
手机中的安卓系统,手机智能生活... 你有没有发现,现在手机里的安卓系统就像是个万能的小助手,无处不在,无所不能呢?它就像是我们生活中的得...
gm8系统是安卓系统吗,安卓生... 你有没有听说过GM8系统?最近这个话题在数码圈里可是挺火的。很多人都在问,GM8系统是安卓系统吗?今...
安卓系统文件非常大,揭秘庞大文... 你有没有发现,最近你的安卓手机越来越卡了?别急,别急,让我来给你揭秘一下这个谜团。没错,就是那个让我...
安卓11系统怎么看,深度解析与... 你有没有发现,你的安卓手机最近是不是变得有点不一样了?没错,安卓11系统已经悄悄地来到了我们的身边。...
安卓p系统是什么,新一代智能体... 你有没有注意到,你的安卓手机最近是不是变得聪明多了?没错,这就是安卓P系统的魔力!今天,就让我带你一...
摩托罗拉安卓13系统,探索创新... 你有没有听说?摩托罗拉的新款手机终于升级到安卓13系统啦!这可是个大新闻,咱们得好好聊聊这个话题。想...
犯罪大师安卓系统在哪下,轻松追... 你有没有听说最近的一款超级火爆的安卓游戏——《犯罪大师》?这款游戏不仅剧情跌宕起伏,角色设定独特,而...
安卓系统升级txt,功能革新与... 你有没有发现,你的安卓手机最近是不是总在提醒你系统要升级了呢?别急,别急,今天就来给你详细说说这个安...
安卓调用系统打开图片,安卓系统... 你有没有遇到过这种情况:手机里存了那么多美美的照片,想分享给朋友,却发现打开图片的步骤竟然那么繁琐?...
安卓不再提示系统更新,轻松告别... 你有没有发现,最近你的安卓手机好像变得特别安静了呢?没错,就是那个一直默默提醒你系统更新的小家伙,它...
安卓系统的如何测试软件,从入门... 你有没有想过,你的安卓手机里那些神奇的软件是怎么诞生的呢?它们可不是凭空出现的,而是经过一系列严格的...
小米8安卓系统版本,安卓系统版... 你有没有发现,手机更新换代的速度简直就像坐上了火箭呢?这不,小米8这款手机自从上市以来,就凭借着出色...
华为手机安卓系统7以上,创新体... 你有没有发现,最近华为手机越来越受欢迎了呢?尤其是那些搭载了安卓系统7.0及以上版本的机型,简直让人...
儿童英语免费安卓系统,儿童英语... 哇,亲爱的家长朋友们,你是否在为孩子的英语学习发愁呢?别担心,今天我要给你带来一个超级好消息——儿童...
ios系统切换安卓系统还原,还... 你有没有想过,有一天你的手机从iOS系统切换到了安卓系统,然后再从安卓系统回到iOS系统呢?这听起来...
灵焕3装安卓系统,引领智能新体... 你知道吗?最近手机圈里可是掀起了一股热潮,那就是灵焕3这款神器的安卓系统升级。没错,就是那个曾经以独...
安卓系统指南针软件,探索未知世... 手机里的指南针功能是不是让你在户外探险时倍感神奇?但你知道吗,安卓系统中的指南针软件可是大有学问呢!...
华为是不用安卓系统了吗,迈向自... 最近有个大新闻在科技圈里炸开了锅,那就是华为是不是不再使用安卓系统了?这可不是一个简单的问题,它涉及...