标签:
前导:开始学习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