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.springframework spring-beans 5.3.18 org.springframework spring-core 5.3.20
一定要注意版本兼容问题,会报异常哦~
输出结果
User{uid='123123', uname='这是我的名字'}
4、Spring ApplicationContext容器
加载XML文件的三种方式
需要ApplicationContext依赖——Spring Context
pom.xml
org.springframework spring-context 5.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的属性
属性 | 描述 |
---|---|
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容器的关系
Spring配置元数据
有哪些方法可以配置元数据给Spring容器
5.2 Spring Bean 作用域
scope有哪些作用域值呢?
什么是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 生命周期
两种重要生命周期
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容器执行顺序:
提供默认初始化和销毁方法
5.4 Spring Bean 后置处理器
什么是Bean 后置处理器? Bean的拓展坞,在初始化前后进行处理
怎么实现后置处理器? BeanPostProcessor接口定义回调方法
注意:
初始化类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:这是我的名字
执行过程顺序:
5.5 Spring Bean 定义继承
bean定义可以包含很多配置信息:包括构造函数参数,属性值,初始化方法,静态工厂方法名等等
继承bean可以重写值,或添加值。
它们之间的关系:与抽象类继承类的关系相同。
Bean 定义模板