Spring启动过程?
<1>创建BeanFactory,解析xml,完成Bean注册
<2>注册BeanFacotryPostProcessor,自定义BeanPostProcessor,AutowiredAnnotationBeanPostProcessor?
<3>执行BeanFactoryPostProcessor,在此可以操作bean定义,使用ClassPathBeanDefinitionScanner扫描@Component(默认,包括@Service,@Controller,@Repository)并注册到IOC
<4>执行BeanPostProcessor,自定义BeanPostProcessor,AutowiredAnnotationBeanPostProcessor?
<5>Bean实例化
<6>Bean属性注入
<7>完成aware接口的注入
<8>执行BeanPostProcessor前置处理
<9>执行Bean初始化:initializeBean、init-method
<10>执行BeanPostProcessor后置处理
Bean有哪几种类型?
普通Bean(Spring创建)、FactoryBean(FactoryBean的getObject方法返回的实例,常用于创建复杂Bean)
这两种Bean都为IOC容器管理
Bean的作用域?
Singleton、Prototype、Request、Session、GlobalSession
Bean生命周期?
postProcessBeanFactory->BeanPostProcessor(postProcessBeforeInitialization)->InitializingBean(afterPropertiesSet)->BeanPostProcessor(postProcessAfterInitialization)
modify bean definition(add bean definition)->modify bean instance(add proxy)
Spring IOC原理?
画图:Bean注册表,Bean实例化,Bean解析,Bean使用
Spring AOP原理?
Spring Bean线程安全?
1、模板方法设计模式
// AbstractApplicationContext.java
Uses the Template Method design pattern,requiring concrete subclasses to implement abstract methods
// 功能:?
// 设计理念:父类定义protected空方法,供子类重写(可选)
protected void initPropertySources() {
// For subclasses: do nothing by default
}
}
// 功能:bean加载具体实现
// 设计理念:定义成抽象方法,要求子类必须重写;
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
// 功能:打印当前类信息
// 设计理念:方法内部使用线程不安全的StringBuilder,提高效率
@Override
public String toString() {
StringBuilder sb = new StringBuilder(getDisplayName());
sb.append(": startup date [").append(new Date(getStartupDate()));
sb.append("]; ");
ApplicationContext parent = getParent();
if (parent == null) {
sb.append("root of context hierarchy");
}
else {
sb.append("parent: ").append(parent.getDisplayName());
}
return sb.toString();
}
BeanFactory.java
public interface BeanFactory {}
// BeanFactory是概念上最基础的Bean容器,像ListableBeanFactory是在此基础上扩展的Bean工厂
// ApplicationContext是实体化后的BeanFactory
// 由于Bean初始化时机是可选的,有的Bean是Lazy-init
// 所以BeanFactory中存储的应该是Map<String,BeanDefinition> 而不直接是 Map<String,Bean>
// 具体是在DefaultListableBeanFactory中Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
BeanDefinition.java
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
boolean isLazyInit();
}
// FactoryBean和普通Bean的区别?
// FactoryBean返回的是内部getObject()方法返回的对象,普通的Bean是直接经过构造函数创建的对象
// 为什么要使用FactoryBean?
// 一个bean的创建过程中涉及到很多其他的bean和多余逻辑,用xml配置比较困难,这时可以考虑用FactoryBean
// 比如org.mybatis.spring.SqlSessionFactoryBean
// 比如AOP中ProxyFactoryBean
public abstract class AbstractApplicationContext extends DefaultResourceLoader
@Override
public void refresh() throws BeansException, IllegalStateException {
}
}
// Spring上下文初始化的入口:
// 模拟一个BeanFactory的初始化过程
// 第一步:资源定位
ClassPathResource classPathResource = new ClassPathResource("beans.xml");
// 第二步:创建Bean工厂容器
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
// 第三步:资源解析器
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);
// 第四步:解析资源定义,并封装到Bean工厂容器中
xmlBeanDefinitionReader.loadBeanDefinitions(classPathResource);
// 第五步:消费Bean
System.out.println("numbers: " + defaultListableBeanFactory.getBeanDefinitionCount());
// 经过Spring封装后的一个BeanFactory的初始化过程
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
// 在 ClassPathXmlApplicationContext中调用refresh(),继而调用父类中的refresh()方法骨架