Spring IOC
简要:Spring 框架俩大特性之一,IOC容器(控制反转):
IOC容器:想象成一个容器,里面存放着众多的Bean,可以帮助我们管理Bean,不需要我们频繁的去创建对象
控制反转:将原来对象的控制权交于IOC容器管理
提示:以下是本篇文章正文内容,下面案例可供参考
一、开始前说明
本人小白,完全是学习中记录,如有不正确的地方请指出,感谢
由于剖析Spring bean的生命周期会遇到相关的接口、方法、对象,所以为了方便阅读,在讲解之前先将一些对象、接口等的说明标注在前,方便读者阅读中进行参考。
1、BeanFactory
从名称就可以理解BeanFactory的意思是Bean工厂
工厂一般都是用来生产对象的,而我们从BeanFactory中可以使用getBean()方法获取我们的Bean对象
2、ClassPathXmlApplicationContext
我们知道,在Spring中可以通过xml的方式定义Bean,而要让这些Bean加载到IOC容器让我们可以使用,则需要在Spring启动的时候让它扫描到定义Bean的xml文件,ClassPathXmlApplicationContext则是帮助我们做这样的一件事情
BeanFactory和ClassPathXmlApplicationContext搭配使用示例:
//1、加载spring配置文件
BeanFactory context = new ClassPathXmlApplicationContext("Spring.xml");
//2、获取配置创建对象 UserBean是我们创建的对象 提前已在Spring。xml中配置 后续会讲
UserBean userBean = beanFactory.getBean("userBean", UserBean.class);
3、BeanDefinition
是进一步对我们Bean对象的抽象,我们创建的Bean(如下UserBean.class对象)并不能很好的描述一些信息,例如Bean是单例还是多例、Bean的注入模型、Bean是否是懒加载、初始化方法、销毁方法等,所以需要BeanDefinition对这些抽象的信息进一步建模,而ClassPathXmlApplicationContext在获取xml文件中定义的Bean信息后会使用BeanDefinitionReader(接口)将这些Bean定义信息读取成BeanDefinition集合
public class UserBean {
private String name;
private Integer age;
public UserBean(String name, Integer age) {
this.name = name;
this.age = age;
}
public UserBean() {
}
public void add(){
System.out.println("userBean注入");
}
}
4、BeanFactoryPostProcessor
BeanFactory后置处理器是会对BeanDefinition对象进行修改,可以在Bean实例化之前调用针对BeanDefinition进行处理,修改属性
```java
public interface BeanFactoryPostProcessor {
/**
* 这个接口只有一个方法入参就是ConfigurableListableBeanFactory
* ConfigurableListableBeanFactory 对象中又一个getBeanDefinition(String beanName)方法可以用其对Bean进行操作修改其属性,
* 例如初始值、单例还是多例、初始化方法等 稍后演示
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
5、BeanPostProcessor
Bean后置处理器,是对生成的Bean对象进行修改,发生在Bean初始化之前和初始化之后,此接口中定义了俩个方法
postProcessBeforeInitialization(Object bean, String beanName)
postProcessAfterInitialization(Object bean, String beanName)
如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中
public interface BeanPostProcessor {
//初始化之前调用 前置处理器
public java.lang.Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//初始化之后调用 后置处理器
public java.lang.Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
二、Spring Bean的生命周期
1、流程图
第一步----创建对象,编写xml文件
1、创建Order对象
public class Order implements BeanNameAware, ApplicationContextAware {
private String name;
private Integer age;
private String beanName;
//全参构造方法
public Order(String name, Integer age, String beanName) {
this.name = name;
this.age = age;
this.beanName = beanName;
}
public Order() {
}
}
2、文件夹resources下创建Spring.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="order" class="com.wss.spring.Order"></bean>
</beans>
第二步----编写测试类 读取xml文件
public class TestCreateBean {
public static void createBean(){
System.out.println("第一步,读取xml文件");
//读取Spring.xml文件
BeanFactory beanFactory = new ClassPathXmlApplicationContext("Spring.xml");
Order order = beanFactory .getBean("order", Order.class);
context.close();
}
public static void main(String[] args) {
createBean();
}
}
第三步----实现BeanFactoryPostProcessor接口
1、实现BeanFactoryPostProcessor接口,并且在方法内利用beanDefinition 给Order对象赋值
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
BeanDefinition beanDefinition =configurableListableBeanFactory.getBeanDefinition("order");
beanDefinition.getPropertyValues().add("name","张三");
System.out.println("第二步 调用BeanFactoryPostProcessor 添加name值:张三");
}
}
2、Spring.xml中添加MyBeanFactoryPostProcessor配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="order" class="com.wss.spring.Order"/>
//添加如下bean定义信息
<bean id="myBeanFactoryPostProcessor" class="com.wss.spring.MyBeanFactoryPostProcessor"/>
</beans>
第四步----编写实例化方法
1、在Order对象中手动编写实例化方法
public class Order implements BeanNameAware, ApplicationContextAware {
private String name;
private Integer age;
private String beanName;
//全参构造方法
public Order(String name, Integer age, String beanName) {
this.name = name;
this.age = age;
this.beanName = beanName;
}
public Order() {
//默认执行对象内部的无参构造方法 利用反射创建实例
System.out.println("第三步 执行无参构造创建bean实例");
}
}
第五步----实现BeanPostProcessor接口
1、实现BeanPostProcessor接口 重写其中的俩个方法
public class MyBeanProcessor implements BeanPostProcessor {
@Override
@Nullable
public java.lang.Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化之前执行方法");
return bean;
}
@Override
@Nullable
public java.lang.Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("初始化之后执行方法");
return bean;
}
}
2、修改Spring.xml定义文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="order" class="com.wss.spring.Order"/>
//添加如下bean定义信息
<bean id="myBeanFactoryPostProcessor" class="com.wss.spring.MyBeanFactoryPostProcessor"/>
<bean id="process" class="com.wss.spring.MyBeanProcessor">
</beans>
第六步----定义初始化方法
1、Order对象内部手动实现初始化方法
public class Order implements BeanNameAware, ApplicationContextAware {
private String name;
private Integer age;
private String beanName;
//全参构造方法
public Order(String name, Integer age, String beanName) {
this.name = name;
this.age = age;
this.beanName = beanName;
}
public Order() {
//默认执行对象内部的无参构造方法 利用反射创建实例
System.out.println("第三步 执行无参构造创建bean实例");
}
public void initMethod() {
System.out.println("第四步 执行初始化的方法");
}
}
2、修改Spring.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
//使用init-method手动配置初始化方法
<bean id="order" class="com.wss.spring.Order" init-method="initMethod" />
//添加如下bean定义信息
<bean id="myBeanFactoryPostProcessor" class="com.wss.spring.MyBeanFactoryPostProcessor"/>
<bean id="process" class="com.wss.spring.MyBeanProcessor">
</beans>
第七步----调用Order实例,输出日志
public class TestCreateBean {
public static void createBean(){
System.out.println("第一步,读取xml文件");
//读取Spring.xml文件
BeanFactory beanFactory = new ClassPathXmlApplicationContext("Spring.xml");
Order order = beanFactory .getBean("order", Order.class);
System.out.println("第五步,获取创建的bean对象");
context.close();
}
public static void main(String[] args) {
createBean();
}
}
第八步----编写销毁方法
1、在我们Order内部编写销毁方法
public class Order implements BeanNameAware, ApplicationContextAware {
private String name;
private Integer age;
private String beanName;
//全参构造方法
public Order(String name, Integer age, String beanName) {
this.name = name;
this.age = age;
this.beanName = beanName;
}
public Order() {
//默认执行对象内部的无参构造方法 利用反射创建实例
System.out.println("第三步 执行无参构造创建bean实例");
}
public void initMethod() {
System.out.println("第四步 执行初始化的方法");
}
public void killMethod() {
System.out.println("第六步 执行销毁的方法");
}
}
2、修改Spring.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
//使用destroy-method手动配置销毁方法
<bean id="order" class="com.wss.spring.Order" init-method="initMethod" destroy-method="killMethod" />
//添加如下bean定义信息
<bean id="myBeanFactoryPostProcessor" class="com.wss.spring.MyBeanFactoryPostProcessor"/>
<bean id="process" class="com.wss.spring.MyBeanProcessor">
</beans>
执行
可以看到和我们一开始定义的流程图一样。