引言
上篇博客讲到的是Spring里的基础Bean,BeanDefinition与BeanFactory三者之间的简单关系,这里主要在此基础
上添加BeanClass的内容,这里顺便提一个问题大家思想下,我会在总结里给出答案的。
问:Bean,BeanClass与BeanClassName三者之间有什么关系?
先上图:
UML图
类图:
时序图:
这里已经将BeanFactory恢复为接口了,AutowireCapableBeanFactory作为实现类,继承抽象类
AbstractBeanFactory中的doCreateBean(),而doCreateBean方法是注册Bean的关键代码。
下边看代码部分吧~
BeanDefinition
package us.codecraft.tinyioc;
/**
* @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;
}
}
BeanFactory
package us.codecraft.tinyioc.factory;
import us.codecraft.tinyioc.BeanDefinition;
/**
* @author yihua.huang@dianping.com
*/
public interface BeanFactory {
Object getBean(String name);
void registerBeanDefinition(String name, BeanDefinition beanDefinition);
}
AbstractBeanFactory
package us.codecraft.tinyioc.factory;
import us.codecraft.tinyioc.BeanDefinition;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @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) {
Object bean = doCreateBean(beanDefinition);
beanDefinition.setBean(bean);
beanDefinitionMap.put(name, beanDefinition);
}
/**
* 初始化bean
* @param beanDefinition
* @return
*/
protected abstract Object doCreateBean(BeanDefinition beanDefinition);
}
AutowireCapableBeanFactory
package us.codecraft.tinyioc.factory; import us.codecraft.tinyioc.BeanDefinition; /** * @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; } }
接下来是测试类:
HelloWorldService
package us.codecraft.tinyioc; /** * @author yihua.huang@dianping.com */ public class HelloWorldService { public void helloWorld(){ System.out.println("Hello World!"); } }
BeanFactoryTest
package us.codecraft.tinyioc; import org.junit.Test; import us.codecraft.tinyioc.factory.AutowireCapableBeanFactory; import us.codecraft.tinyioc.factory.BeanFactory; /** * @author yihua.huang@dianping.com */ 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(); } }
总结
根据上边的图和代码,能看出来Bean,BeanClass和BeanClassName三者之间的关系了吗?在测试类
BeanFactoryTest中可以看到setBeanClassName方法,参数是字符串,字符串的内容是HelloWorldService的物理全路
径,在
setBeanClassName方法内部,通过反射,将全路径读出,存入到BeanClass里,并由BeanDefinition进行管
理,完成赋值过程。注册部分与上篇博客基本类似,这里不再赘述。
在上述整个方法里有没有看到不和谐的地方?HelloWorldService里还是输入的字符串商量,在程序中当然是不允
许的,所以下篇博客,我们将在BeanDefinition里引入PropertyValue,期待吧~