Spring IoC容器-BeanFactory
SpringIoC容器用来容纳我们开发的各种Bean,并且我们可以从中获取各种发布在Spring IoC容器中的Bean,并通过描述来获取它。
Spring Ioc容器的设计
Spring IoC容器的设计主要是基于BeanFactory和ApplicationContext两个接口,其中ApplicationContext是BeanFactory的子接口,BeanFactory是Spring IoC容器所定义的最底层的接口,ApplicationContext是其高级接口之一,并且对BeanFactory的功能做了增强,所以我们主要使用ApplicatinContext作为Spring IoC的容器。
IOC接口设计
BeanFactory类的体系结构
Spring为BeanFactory提供了很多的实现类,如图
- BeanFactory:该接口位于类接口的顶层,它主要的方法就是getBean(String beanName),该方法送容器中返回特定名称的Bean,BeanFactory的功能通过其他接口得到不断扩展。
- ListableBeanFactory:该接口定义了访问容器中Bean基本信息的若干方法,如查看Bean的个数,获取某一类型Bean的配置名,查看容器中是否包含某一个Bean等。
- HierarchicalBeanFactory:父子级联IoC容器的接口,子容器可以通过接口方法访问父容器。
- ConfigurableBeanFactory:这个接口增强了IoC容器的可定制性,它定义了设置类装载器,属性编辑器,容器初始化后置处理器等方法
- AutowireCapableBeanFactory:定义了将容器中的Bean按某种规则(如按名字匹配,按类型匹配等)进行自动装配的方法
- SingletonBeanRegistry:定义了允许在运行期向容器注册单个实例Bean的方法
- BeanDefinitionRegistry:Spring配置文件中每一个节点元素在Spring里都通过一个BeanDefinition对象表示,它描述了Bean的配置信息。而接口BeanDefinitionRegistry接口提供了向容器手工注册BeanDefinition对象的方法。
BeanFactory的Bean的生命周期
具体过程
- 当调用者通过getBean(beanName)向容器中请求某一个Bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,则在实例化Bean之前,将调用接口postProcessBeforeInstantiation方法。具体可以查看AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd)方法
- 根据配置情况调用Bean构造函数或工厂方法实例化Bean。可以查看AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)方法
- 如果容器注册了InstantiationAwareBeanPostProcessor接口,那么在实例化Bean之后,调用该接口的postProcessAfterInstantiation方法,可在这里对已经实例化的对象进行一些处理
- 如果Bean配置了属性信息,那么容器在这一步着手将配置设置到Bean队形的属性中,不过在设置每个属性之前将先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法
- 调用Bean的属性设置方法设置属性值
- 如果Bean实现了org.springframework.beans.factory.BeanNameAware接口,则将调用setBeanName接口方法,将配置文件中该Bean对应的名称设置到Bean中
- 如果Bean实现了org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory接口方法,将BeanFactory容器实例设置到Bean中
- 如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,则调用BeanPostProcessor的Object postProcessBeforeInitialization(Object bean, String beanName) 接口方法对Bean进行加工操作,其中,入参bean是当前正处理的Bean,而beanName是当前Bean的配置名,返回的对象为加工处理后的Bean。用户可以使用该方法对某些Bean进行特殊的处理,甚至改变Bean的行为
- 如果Bean实现了InitializingBean接口,则将调用接口的afterPropertiesSet()方法
- 如果在bean中通过init-method属性定义了初始化方法,则将执行这个方法
- BeanPostProcessor后处理器定义了两个方法,postProcessBeforeInitialization()在第八步调用,Object postProcessAfterInitialization(Object bean, String beanName)这个方法在此时调用,容器再次获得对Bean加工处理的机会
- 如果在bean中指定Bean的作用范围为scope="prototype",则将Bean返回给调用者,调用者负责Bean后续的生命管理,Spring不再管理这个Bean的生命周期。如果将作用范围设置为scope="singleton",则将Bean放入Spring IoC容器的缓存池中,并将Bean引用返回给调用者,Spring继续对这些Bean进行后续的生命周期管理
- 对于scope="singleton"的Bean,当容器关闭时,将触发Spring对Bean后续生命周期的管理工作。如果Bean实现了DisposableBean接口,则将调用接口的destory()方法,可以再次编写释放资源、记录日志等操作
- 对于scope="singleton"的Bean,如果通过Bean的destroy-method属性执行了Bean的销毁方法,那么Spring将执行Bean的这个方法,完成Bean资源释放等操作
Bean声明周期实例
定义一个Bean类并实现BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean接口
public class Animal implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean { private String name; private int age; private BeanFactory beanFactory; private String beanName; public Animal() { System.out.println("调用Animal的构造方法"); } public void setName(String name) { System.out.println("调用AnimalsetName设置属性"); this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("调用BeanFactoryAware.setBeanFactory()"); this.beanFactory = beanFactory; } @Override public void setBeanName(String beanName) { System.out.println("调用BeanNameAware.setBeanName()。"); this.beanName = beanName; } @Override public void afterPropertiesSet() throws Exception { System.out.println("调用InitializingBean.afterPropertiesSet()。"); } @Override public void destroy() throws Exception { System.out.println("调用DisposableBean.destory()。"); } public void myInit() { System.out.println("调用myInit(),"); } public void myDestory() { System.out.println("调用myDestroy()。"); } @Override public String toString() { return "Animal{" + "name='" + name + '\'' + ", age=" + age + ", beanFactory=" + beanFactory + '}'; } }
定义一个MyInstantiationAwareBeanPostProcessor并继承InstantiationAwareBeanPostProcessorAdapter
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if ("animal".equals(beanName)) { System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation"); } return super.postProcessBeforeInstantiation(beanClass, beanName); } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if ("animal".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation"); } return super.postProcessAfterInstantiation(bean, beanName); } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if ("animal".equals(beanName)) { System.out.println("InstantiationAwareBeanPostProcessor.postProcessPropertyValues"); } return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return super.postProcessBeforeInitialization(bean, beanName); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return super.postProcessAfterInitialization(bean, beanName); } }
定义一个MyBeanPostProcessor并实现BeanPostProcessor接口
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("animal")){ Animal animal=(Animal)bean; System.out.println("调用MyBeanPostProcessor.postProcessAfterInitialization(): "+animal); } return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("animal")){ Animal animal=(Animal)bean; System.out.println("调用MyBeanPostProcessor.postProcessBeforeInitialization(): "+animal); } 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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd"> <bean id="animal" class="com.rookie.bigdata.factory.domain.Animal" destroy-method="myDestory" init-method="myInit"> <property name="name" value="哈士奇"></property> <property name="age" value="3"></property> </bean> </beans>
编写测试类
public class BeanFactoryMain { public static void main(String[] args) { ResourcePatternResolver resolver=new PathMatchingResourcePatternResolver(); Resource resource = resolver.getResource("classpath:beanfactory/beans.xml"); DefaultListableBeanFactory factory=new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader=new XmlBeanDefinitionReader(factory); reader.loadBeanDefinitions(resource); Person person = (Person)factory.getBean("person"); System.out.println(person); } }
这样在运行测试类,就可以看到BeanFactory的整个运行的声明周期过程啦。
相关推荐
smalllove 2020-07-27
willluckysmile 2020-06-29
willluckysmile 2020-06-10
MrFuWen 2020-06-09
yuanye0 2020-06-08
somyjun 2020-05-01
tianxiaolu 2020-04-06
吾日五省我身 2020-03-28
itjavashuai 2020-07-28
TiDBPingCAP 2020-06-21
丽丽 2020-06-11
shenxiuwen 2020-06-10
whbing 2020-05-19
yuanye0 2020-05-14
kong000dao0 2020-05-10
方志朋 2020-05-08
suixinsuoyu 2020-04-29
咻pur慢 2020-04-22