一、总框架加载流程
1.applicationContext创建beanFactory->
2.beanFactory通过XMLbeandefineReader解析文件,获取BeanDefinition,并注册到beanfactory中。这时只是把定义放到工厂,并没有真正生成实例。
3.中间会调用beanfactoryPostProcesser的BEAN,在这种可以自定义加载扩展BEAN的流程。
4.finishBeanFactoryInitialization对所有非延迟加载的单例BEAN进行实例化,此时会创建对象,然后会先调用beanPostProcesser的before接口,插入属性, 然后注入属性到对象中,后面调用beanPostProcesser的after接口修改属性。通过beanWrapperImpl.
二、XML方式加载流程。
1.使用ClassPathXmlApplicationContext加载BEAN创建的XML文件。
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring1.xml");
PeopleBean peopleBean = (PeopleBean) classPathXmlApplicationContext.getBean("people1");
System.out.println(" name: "+ peopleBean.getName());
IPeopleService peopleService = (IPeopleService) classPathXmlApplicationContext.getBean("peopleService");
三、通过注解扫描加载流程。
1.使用ClassPathXmlApplicationContext加载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:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--使用context命名空间,通知spring扫描指定目录,进行注解的解析-->
<context:component-scan base-package="com.tpw.newday.service.people"/>
<bean id="people1" class="com.tpw.newday.bean.PeopleBean">
<property name="name" value="zhangsan"/>
</bean>
<bean id="people2" class="com.tpw.newday.bean.PeopleBean">
<property name="name" value="lisi"/>
</bean>
<bean id="people3" class="com.tpw.newday.bean.PeopleBean">
<property name="name" value="wangwu"/>
</bean>
<bean id="peopleConfig" class="com.tpw.newday.config.PeopleConf">
</bean>
<bean id="peopleService" class="com.tpw.newday.service.people.PeopleServiceImpl">
<property name="peopleBean1" ref="people1"/>
<property name="peopleBean2" ref="people2"/>
</bean>
</beans>
PeopleServiceImpl源码:
package com.tpw.newday.service.people;
import cn.hutool.json.JSONUtil;
import com.tpw.newday.bean.PeopleBean;
import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import javax.annotation.Resource;
/**
* <h3>newday</h3>
* <p></p>
*
* @author : lipengyao
* @date : 2021-06-25 09:53:24
**/
@Data
public class PeopleServiceImpl implements IPeopleService,InitializingBean,BeanNameAware,BeanClassLoaderAware
,BeanFactoryAware{
private PeopleBean peopleBean1;
private PeopleBean peopleBean2;
@Resource(name = "people3")
private PeopleBean peopleBean3;
@Override
public void save(PeopleBean peopleBean) {
System.out.println("PeopleServiceImpl--> save peopleBean:" + JSONUtil.toJsonStr(peopleBean));
}
@Override
public PeopleBean getPeople(int index) {
PeopleBean peopleBean = null;
switch (index){
case 1:
peopleBean = peopleBean1;
break;
case 2:
peopleBean = peopleBean2;
break;
case 3:
peopleBean = peopleBean3;
break;
}
System.out.println("PeopleServiceImpl--> getPeople peopleBean:" + JSONUtil.toJsonStr(peopleBean));
return peopleBean;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("PeopleServiceImpl--> afterPropertiesSet PeopleServiceImpl:" );
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println(" PeopleServiceImpl-->setBeanClassLoader name:" + classLoader.getClass().getName());
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
PeopleBean peopleBeanxx = (PeopleBean) beanFactory.getBean("people1");
System.out.println(" PeopleServiceImpl-->setBeanFactory name:" + peopleBeanxx.getName());
}
@Override
public void setBeanName(String name) {
System.out.println(" PeopleServiceImpl--> setBeanName name:" + name );
}
}
2.spring的XML解析器解析component-scan标签时,会触发composerScanParser,此类为自动扫描指定包下的component注解类到beanfactory,然后再注入configPostProcesser,
AutowiredAnnotationBeanPostProcessor,
CommonAnnotationBeanPostProcessor,
internalEventListenerProcessor,
internalEventListenerFactory,
internalPersistenceAnnotationProcessor,
3.在每个BEAN实例化后,会首先调用系统中MergedBeanDefinitionPostProcessor所有接口的
postProcessMergedBeanDefinition,
CommonAnnotationBeanPostProcessor类就会在这个实现中查找当前类所有带有resource注解的属性和方法,并且保存到InjectionMetadata中。并将属性设置到BeanFactory的externPropertiesmap中,AutowiredAnnotationBeanPostProcessor则是查找带有autowired,注解的属性和方法,原理一样。
4.在填充对象属性时populateBean函数会调用所有实现
InstantiationAwareBeanPostProcessor接口的对象的postProcessProperties方法,将上面保存的属性通过反射设置到对象属性中。