标签:
前导:开始学习Spring核心思想,通过一个山寨精简版Spring代码结合学习。
内容:1. BeanReference-保存Bean的引用。 2. getBean()中调用createBean()-lazy-init。这次我们用到了在Bean中注入Bean的情况,在这里我们再一次改写了AbstractBeanFactory,改写后的AbstractBeanFactory将多出一个List来保存所有注册的对象名,而且我们不再是注册时候就创建bean,并将beanDefinition的bean注入放到了具体的实现,实现懒加载,因为我们知道并不是注册后一定会用到这个bean,因此我们放到了getBean()的时候再实例化bean;AbstractBeanFactory中的preInstantiateSingletons()可以实现所有bean的初始化;AutowireCapableBeanFactory类要注意的地方是applyPropertyValues()这个函数,我们在这里要多出类中引用的注入。
BeanReference:
public class BeanReference {
private String name;
private Object bean;
public BeanReference(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getBean() {
return bean;
}
public void setBean(Object bean) {
this.bean = bean;
}
}BeanFactory:
public interface BeanFactory {
Object getBean(String name) throws Exception;
void registerBeanDefinition(String name, BeanDefinition beanDefinition) throws Exception;
}AbstractBeanFactory:
public abstract class AbstractBeanFactory implements BeanFactory{
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
private final List<String> beanDefinitionNames = new ArrayList<String>();
@Override
public Object getBean(String name) throws Exception {
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
if (beanDefinition == null)
throw new IllegalArgumentException("No bean named " + name + "is defined");
Object bean = beanDefinition.getBean();
if (bean == null) bean = doCreateBean(beanDefinition);
return bean;
}
@Override
public void registerBeanDefinition(String name,
BeanDefinition beanDefinition) throws Exception{
//TODO 这里不再是注册时候就创建bean,并将beanDefinition的bean注入放到了具体的实现,实现懒加载
beanDefinitionMap.put(name, beanDefinition);
beanDefinitionNames.add(name);
}
public void preInstantiateSingletons() throws Exception {
for (Iterator<String> it = this.beanDefinitionNames.iterator(); it.hasNext();) {
String beanName = (String) it.next();
getBean(beanName);
}
}
/**
* 初始化bean
* @param beanDefinition
* @return
*/
protected abstract Object doCreateBean(BeanDefinition beanDefinition) throws Exception;
}
/**
* 可自动装载内容的BeanFactory
* @author acer
*
*/
public class AutowireCapableBeanFactory extends AbstractBeanFactory{
@Override
protected Object doCreateBean(BeanDefinition beanDefinition) throws Exception{
Object bean = createBeanInstance(beanDefinition);
//notice,我们在这里要完成bean的注入
beanDefinition.setBean(bean);
applyPropertyValues(bean, beanDefinition);
return bean;
}
protected Object createBeanInstance(BeanDefinition beanDefinition) throws Exception {
return beanDefinition.getBeanClass().newInstance();
}
protected void applyPropertyValues(Object bean, BeanDefinition mbd) throws Exception {
for (PropertyValue propertyValue : mbd.getPropertyValues().getPropertyValueList()) {
Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());
declaredField.setAccessible(true);
Object value = propertyValue.getValue();
if (value instanceof BeanReference) {
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getName());
}
declaredField.set(bean, value);
}
}
}
public class HelloWorldService {
private String text;
private OutputService outputService;
public void helloWorld(){
outputService.output(text);
}
public void setText(String text) {
this.text = text;
}
public void setOutputService(OutputService outputService) {
this.outputService = outputService;
}
}OutputService:
public class OutputService {
private HelloWorldService helloWorldService;
public void output(String text) {
Assert.assertNotNull(helloWorldService);
System.out.println(text);
}
public void setHelloWorldService(HelloWorldService helloWorldService) {
this.helloWorldService = helloWorldService;
}
}
public class BeanFactoryTest {
@Test
public void testPreInstantiate() throws Exception{
// 1.读取配置
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());
xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml");
// 2.初始化BeanFactory并注册bean
AbstractBeanFactory beanFactory = new AutowireCapableBeanFactory();
for (Map.Entry<String, BeanDefinition> beanEntry : xmlBeanDefinitionReader.getRegistry().entrySet())
beanFactory.registerBeanDefinition(beanEntry.getKey(), beanEntry.getValue());
// 3.初始化bean
beanFactory.preInstantiateSingletons();
// 4.获取bean
HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
helloWorldService.helloWorld();
}
@Test
public void testLazy() throws Exception {
// 1. 读取配置
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(new ResourceLoader());
xmlBeanDefinitionReader.loadBeanDefinitions("tinyioc.xml");
// 2. 初始化BeanFactory并注册bean
AbstractBeanFactory beanFactory = new AutowireCapableBeanFactory();
for (Map.Entry<String, BeanDefinition> beanEntry : xmlBeanDefinitionReader.getRegistry().entrySet())
beanFactory.registerBeanDefinition(beanEntry.getKey(), beanEntry.getValue());
// 3. 获取bean
HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
helloWorldService.helloWorld();
}
}
<?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: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-2.5.xsd">
<bean name="outputService" class="step5.test.OutputService">
<property name="helloWorldService" ref="helloWorldService"></property>
</bean>
<bean name="helloWorldService" class="step5.test.HelloWorldService">
<property name="text" value="Hello World! from step5!"></property>
<property name="outputService" ref="outputService"></property>
</bean>
</beans>标签:
原文地址:http://blog.csdn.net/u011345136/article/details/45641215