这几天一直在看spring的源码,也多亏了JE上jiwenke大哥的ioc解析,让我有种播开乌云见天日的感觉。就像武侠剧里的楞头小年青,捡了本不世秘笈,功力尚浅,差点走火入魔。spring真的是博大精深的家伙,它把一些深层次的东西都隐藏了,让人只看到表面的东东。本文就是针对于此,通过硬编码的方式,更加的了解spring ioc的实现机制。
Spring IoC 容器和上下文的初始化包括Bean定义信息的资源定位,载入和注册过程,这里采用了硬编码忽略掉定义信息的资源定位这一环节。
DefaultSingletonBeanRegistry
---AbstractBeanFactory
---AbstractAutowireCapableBeanFactory
---DefaultListableBeanFactory
---XmlBeanFactory
XmlBeanFactory把DefaultListableBeanFactory作为ioc容器的实现
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory)
throws BeansException
{
super(parentBeanFactory);
reader = new XmlBeanDefinitionReader(this);
reader.loadBeanDefinitions(resource);
}
下面先介绍下几个概念:
BeanDefinition Bean定义信息
BeanFactory Bean工厂
BeanDefinitionRegistry 注册器的接口
MutablePropertyValues 属性集合类
RootBeanDefinition BeanDefinition的实现
public class DaoA implements IDaoA {
private String param;
public void operationA() {
System.out.println("DaoA.operationA(" + param + ")");
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
public class DaoB implements IDaoB {
public void operationB() {
System.out.println("DaoB.operationB()");
}
}
public class Service implements IService {
private IDaoA daoA = null;
private IDaoB daoB = null;
public void service() {
System.out.println("********service begin ***********");
daoA.operationA();
daoB.operationB();
System.out.println("********service end *************");
}
public IDaoA getDaoA() {
return daoA;
}
public void setDaoA(IDaoA daoA) {
this.daoA = daoA;
}
public IDaoB getDaoB() {
return daoB;
}
public void setDaoB(IDaoB daoB) {
this.daoB = daoB;
}
}
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class HardCodeIoc {
public static void main(String[] args) {
// 注册器
BeanDefinitionRegistry register = new DefaultListableBeanFactory();
/**//* DaoA的属性集(DaoB没有属性这里就不做表示) */
MutablePropertyValues daoAProperties = new MutablePropertyValues();
daoAProperties.addPropertyValue("param", "param1");
/**//* Service的属性集 */
MutablePropertyValues serviceProperties = new MutablePropertyValues();
serviceProperties.addPropertyValue("daoA", new RuntimeBeanReference("daoA"));
serviceProperties.addPropertyValue("daoB", new RuntimeBeanReference("daoB"));
/**//* 分别构造DaoA,DaoB,Service的Bean定义信息 */
RootBeanDefinition daoADefinition = new RootBeanDefinition(DaoA.class, daoAProperties);
RootBeanDefinition daoBDefinition = new RootBeanDefinition(DaoB.class, null);
RootBeanDefinition serviceDefinition = new RootBeanDefinition(Service.class, serviceProperties);
/**//* 把DaoA,DaoB,Service注册到工厂 */
register.registerBeanDefinition("daoA", daoADefinition);
register.registerBeanDefinition("daoB", daoBDefinition);
register.registerBeanDefinition("service", serviceDefinition);
// 转化为Bean工厂容器
BeanFactory beanFactory = (BeanFactory) register;
IDaoA daoA = (IDaoA) beanFactory.getBean("daoA");
IDaoB daoB = (IDaoB) beanFactory.getBean("daoB");
IService service = (IService) beanFactory.getBean("service");
daoA.operationA();
daoB.operationB();
service.service();
}
}
打印结果如下:
DaoA.operationA(param1)
DaoB.operationB()
********service begin ***********
DaoA.operationA(param1)
DaoB.operationB()
********service end *************
了解了这几个概念后就可以利用BeanFactory的后配置处理配合annotation进行自动注入了,省却了xml配置的麻烦。