一、IOC和DI
- IOC(反转控制):将对象的创建交给spring进行配置。
- DI(依赖注入):向类里的属性设置值。
IOC和DI的关系:DI不能单独存在,需要在IOC的基础上完成。
二、Bean的作用域
Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。
Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。
三、Bean的生命周期
Bean 生命周期的整个执行过程描述如下。
1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。
Spring 为 Bean 提供了细致全面的生命周期过程,通过实现特定的接口或 的属性设置,都可以对 Bean 的生命周期过程产生影响。虽然可以随意配置 的属性,但是建议不要过多地使用 Bean 实现接口,因为这样会导致代码和 Spring 的聚合过于紧密。
生命周期验证
Person类:
package com.seven.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Person implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,
InitializingBean, DisposableBean {
private String name;
public void setBeanName(String name) {
System.out.println("执行了 BeanNameAware 接口的 setBeanName 方法");
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("执行了 BeanFactoryAware 接口的 setBeanFactory 方法");
}
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("执行了 ApplicationContextAware 接口的 setApplicationContext 方法");
}
public void afterPropertiesSet() throws Exception {
System.out.println("执行了 InitializingBean 接口的 afterPropertiesSet 方法");
}
public void myInitMethod() {
System.out.println("执行了 自定义 的 初始化 方法");
}
public void destroy() throws Exception {
System.out.println("执行了 DisposableBean 接口的 destroy 方法");
}
public void myDestoryMethod() {
System.out.println("执行了 自定义 的 销毁 方法");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("设置属性值");
this.name = name;
}
}
MyBeanPostProcessor类:
package com.seven.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行了 BeanPostProcessor 接口的 postProcessBeforeInitialization 方法");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("执行了 BeanPostProcessor 接口的 postProcessAfterInitialization 方法");
return bean;
}
}
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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.seven.bean.Person" init-method="myInitMethod" destroy-method="myDestoryMethod">
<property name="name" value="设置了name的值"/>
</bean>
<bean class="com.seven.bean.MyBeanPostProcessor"/>
</beans>
测试类:
import com.seven.bean.Person;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CycleTest {
private ApplicationContext context;
@Before
public void init() {
context = new ClassPathXmlApplicationContext("spring.config.xml");
}
@After
public void destory() {
((ClassPathXmlApplicationContext) context).close();
}
@Test
public void test() {
System.out.println("------------------------------");
Person person = (Person) context.getBean("person");
System.out.println("使用了一下这个bean");
}
}
执行结果: