读懂Spring核心系列2(工厂模式)
在上一篇中我们实现了一个简单的注入和获取bean的功能,接着我们对上一次的代码进行重构与优化
上一篇的BeanFactory类实现了registerBeanDefinition的方法,这一次我们将它抽出来作为借口
下面就是AbstractBeanFactory类,它将实现上面的接口
应该注意到上面类中,doCreateBean方法是抽象的,有待他的子类进行实现。这就是我们这一篇中标题所谓工厂方法的出处。我们将doCreateBean延迟实现的原因是什么?最后我们将分析原因。
下面的类继承上面的AbstractBeanFactory,在这里实现了doCreateBean方法
看过上面的三个类后,还有冰山的一角没有揭开,就是BeanDefinition ,这个在上面一直出现的类的具体实现
到此,我们系列2的框架已经完成了,仔细看到这的同学已经可以使用上面的类实现Bean的装配和获取。 首先:我们应该初始化BeanDefinition ,因为它包装了我们自己编写,需要装配的类。 其次:将BeanDefinition注册到工厂中 最后:获取bean,调用bean
下面是四个步骤的源码
当然,HelloWorldService这一个作为使用框架的人编写的bean也不能被漏掉
最后补充的是registerBeanDefinition方法的第一个参数,根据它来获取bean,我们使用Spring时,配置文件中bean的ID就是这样的功能。
至于doCreateBean需要延迟实现,是因为我们将有多种实例化bean的方式,Spring就有什么根据xml和注解等方式。当然,其中又细分许多种,像构造器,set方法等。我们根据设计模式,将不同的实现封装到不同的子类中。
上一篇:http://blog.csdn.net/wdqqmms00544kiss/article/details/30294703
上一篇的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