在上一篇中我们实现了一个简单的注入和获取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