码迷,mamicode.com
首页 > 编程语言 > 详细

Spring核心学习(5)将Bean注入Bean-解析依赖

时间:2015-05-11 10:47:47      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

前导:开始学习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;
}

AutowireCapableBeanFactory:

/**
 * 可自动装载内容的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);
		}
	}
}

HelloWorldService:

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;
	}
}

BeanFactoryTest:

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();
	}
	
}

tinyioc.xml:

<?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>





Spring核心学习(5)将Bean注入Bean-解析依赖

标签:

原文地址:http://blog.csdn.net/u011345136/article/details/45641215

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!