spring ioc容器源码最重要的是这两部分,一部分是创建bean容器,加载、注册bean,一部分是实例化(初始化)bean,本篇文章是针对第一部分进行分析的。
IOC容器的简单使用
获取IOC容器
public static void main(String[] args){
ApplicationContext ac=new ClassPathXmlApplicationContext("classpath:application.xml");
}
在maven中添加spring-context的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
//spring-context会自动将spring-core,spring-beans,spring-aop,spring-expression这几个jar包导入进来
实现往容器中加入bean
1.首先定义一个接口
public interface Fruit{
String getFruit();
}
2.定义接口实现类
public class Apple implements Fruit{
@Override
public String getFruit(){
return "Apple";
}
}
3.在resource目录下新建一个配置文件application.xml
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName">
<bean id="fruit" class="com.lx.example.Apple"/>
</beans>
4.通过以下代码运行实例
public class Demo{
public static void main(String[] args){
//获取容器
ApplicationContext ac=ClassPathXmlApplicationContext("classpath:classpath:application.xml");
//从容器中获取对象,而不是通过new的方式创建对象,降低程序间的耦合
Fruit fruit=ac.getBean(Fruit.class);
//这句将打印:Apple
System.out.println(fruit.getFruit());
}
}
接下来,通过具体深入到这个简单的实例中来进行分析
BeanFactory的介绍
BeanFactory,就是生产和管理bean的工厂,具体的类图和继承关系如下
这里具体分析几个特别的BeanFactory
ListableBeanFactory,这个接口可以获取多个bean,最上层的BeanFactory是获取单个bean
HierarchicalBeanFactory,Hierarchical 单词本身能说明问题了,在应用中我们可以有多个BeanFactory,然后设置它们之间的父子关系,加载子BeanFactory时,先加载父BeanFactory
AutowireCapableBeanFactory ,@Autowire也是我们经常用到的关键字,用于BeanFactory自动装载bean,ApplicationContext并没有继承这个这个接口,而是通过getAutowireCapableBeanFactory()方法来获取
ApplicationContext继承了ListableBeanFactory和HierarchicalBeanFactory,没有继承AutowireCapableBeanFactory,但没有继承不代表不能使用,ApplicationContext接口定义中最后一个方法getAutowireCapableBeanFactory()可以获取
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private Resource[] configResources;
//如果需要配置成父子关系,调用这个构造方法
public ClassPathXmlApplicationContext(ApplicationContext parent) {
super(parent);
}
...
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
//根据提供的路径,处理成配置文件数组
setConfigLocations(configLocations);
if (refresh) {
//核心方法
refresh();
}
}
...
}
refresh()方法,重点
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备工作
prepareRefresh();
//获取容器
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//预处理
prepareBeanFactory(beanFactory);
try {
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
//调用 BeanPostProcessor接口的postProcessBeforeInitialization和postProcessAfterInitialization
registerBeanPostProcessors(beanFactory);
initMessageSource();
//钩子方法
onRefresh();
registerListeners();
//初始化所有的 singleton beans(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
cancelRefresh(ex);
// 把异常往外抛
throw ex;
} finally {
resetCommonCaches();
}
}
}
obtainFreshBeanFactory(),创建bean容器,加载注册bean
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean
refreshBeanFactory();
//创建的 BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
进入到refreshBeanFactory()方法
protected final void refreshBeanFactory() throws BeansException {
//当前 ApplicationContext 是否有 BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//初始化一个 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//序列化
beanFactory.setSerializationId(getId());
//设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
customizeBeanFactory(beanFactory);
//加载 Bean 到 BeanFactory 中
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
其中customizeBeanFactory(beanFactory),
设置是否允许BeanDefinition覆盖和是否允许循环引用,默认情况下,如果在同一配置文件中重复了,会报错,如果不是同一配置文件中,会发生BeanDefinition覆盖。同时,默认情况下,spring允许循环依赖
loadBeanDefinitions(beanFactory) 方法,加载bean
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//实例化一个 XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
//加载beanDefinition
loadBeanDefinitions(beanDefinitionReader);
}
处理XML每个元素
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//处理每个xml中的元素
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
解析和注册bean
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 解析
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 注册
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(
bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
这一步中,通过parseBeanDefinitionElement将XML的元素解析为BeanDefinition,然后存在BeanDefinitionHolder中,然后再利用BeanDefinitionHolder将BeanDefinition注册
注册bean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final Object[] args) {
//初始化bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//初始化bean的实例,注入属性
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
// ... ...
}