现在的位置: 首页 > 综合 > 正文

读懂Spring核心系列2(工厂模式)

2018年05月28日 ⁄ 综合 ⁄ 共 3160字 ⁄ 字号 评论关闭
在上一篇中我们实现了一个简单的注入和获取bean的功能,接着我们对上一次的代码进行重构与优化

上一篇的BeanFactory类实现了registerBeanDefinition的方法,这一次我们将它抽出来作为借口
/**
 * @author yihua.huang@dianping.com
 */
public interface BeanFactory {

    Object getBean(String name);

    void registerBeanDefinition(String name, BeanDefinition beanDefinition);
}
下面就是AbstractBeanFactory类,它将实现上面的接口
/**
 * @author yihua.huang@dianping.com
 */
public abstract class AbstractBeanFactory implements BeanFactory {

	private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();

	@Override
        public Object getBean(String name) {
		return beanDefinitionMap.get(name).getBean();
	}

	@Override
        public void registerBeanDefinition(String name, BeanDefinition beanDefinition) {
        <span style="white-space:pre">	</span>Object bean = doCreateBean(beanDefinition);
        <span style="white-space:pre">	</span>beanDefinition.setBean(bean);
        <span style="white-space:pre">	</span>beanDefinitionMap.put(name, beanDefinition);
	}

    /**
     * 初始化bean
     * @param beanDefinition
     * @return
     */
    protected abstract Object doCreateBean(BeanDefinition beanDefinition);

}
应该注意到上面类中,doCreateBean方法是抽象的,有待他的子类进行实现。这就是我们这一篇中标题所谓工厂方法的出处。我们将doCreateBean延迟实现的原因是什么?最后我们将分析原因。
下面的类继承上面的AbstractBeanFactory,在这里实现了doCreateBean方法
/**
 * @author yihua.huang@dianping.com
 */
public class AutowireCapableBeanFactory extends AbstractBeanFactory {

    @Override 
    protected Object doCreateBean(BeanDefinition beanDefinition) {
        try {
            Object bean = beanDefinition.getBeanClass().newInstance();
            return bean;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }
}
看过上面的三个类后,还有冰山的一角没有揭开,就是BeanDefinition ,这个在上面一直出现的类的具体实现
/**
 * @author yihua.huang@dianping.com
 */
public class BeanDefinition {

	private Object bean;

	private Class beanClass;

	private String beanClassName;

	public BeanDefinition() {
	}

	public void setBean(Object bean) {
		this.bean = bean;
	}

	public Class getBeanClass() {
		return beanClass;
	}

	public void setBeanClass(Class beanClass) {
		this.beanClass = beanClass;
	}

	public String getBeanClassName() {
		return beanClassName;
	}

	public void setBeanClassName(String beanClassName) {
		this.beanClassName = beanClassName;
		try {
			this.beanClass = Class.forName(beanClassName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	public Object getBean() {
		return bean;
	}

}
到此,我们系列2的框架已经完成了,仔细看到这的同学已经可以使用上面的类实现Bean的装配和获取。
首先:我们应该初始化BeanDefinition ,因为它包装了我们自己编写,需要装配的类。
其次:将BeanDefinition注册到工厂中
最后:获取bean,调用bean
下面是四个步骤的源码
public class BeanFactoryTest {

	@Test
	public void test() {
		// 1.初始化beanfactory
		BeanFactory beanFactory = new AutowireCapableBeanFactory();

		// 2.注入bean
		BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setBeanClassName("us.codecraft.tinyioc.HelloWorldService");
		beanFactory.registerBeanDefinition("helloWorldService", beanDefinition);

               //3.获取bean
               HelloWorldService helloWorldService = (HelloWorldService) beanFactory.getBean("helloWorldService");
               helloWorldService.helloWorld();

    }
}
当然,HelloWorldService这一个作为使用框架的人编写的bean也不能被漏掉
/**
 * @author yihua.huang@dianping.com
 */
public class HelloWorldService {

    public void helloWorld(){
        System.out.println("Hello World!");
    }
}
最后补充的是registerBeanDefinition方法的第一个参数,根据它来获取bean,我们使用Spring时,配置文件中bean的ID就是这样的功能。

至于doCreateBean需要延迟实现,是因为我们将有多种实例化bean的方式,Spring就有什么根据xml和注解等方式。当然,其中又细分许多种,像构造器,set方法等。我们根据设计模式,将不同的实现封装到不同的子类中。
上一篇:http://blog.csdn.net/wdqqmms00544kiss/article/details/30294703

抱歉!评论已关闭.