在上一篇中,我们简单实现了一个基本的IOC容器,只能完成简单的存,取对象,在使用的时候还得自己实例化之后,把对象给放进去,问题实在是太多了,我们一个一个解决
容器管理实例化
为了使框架能够使用,我们需要将类的实例化过程交给容器来进行管理,要不然使用容器的意义就没有了,也没办法做到解耦.
为了实现这个目的,我们需要将上一篇中的类BeanFactory
扩展一下.
我们额外定义一个类BeanDefinition
来对Bean
进行封装,来存储一些Bean
必须的属性.
BeanDefinition
的代码如下:
public class BeanDefinition {
private Object bean;
public Object getBean() {
return bean;
}
public void setBean(Object bean) {
this.bean = bean;
}
}
由于现在还没有需要保存的额外信息,我们先定义出来.
然后,BeanFactory
就不直接管理Bean
对象了,而是管理Bean
的装饰类BeanDefinition
.
代码如下:
public class BeanFactory {
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
public Object getBean(String beanName) {
return beanDefinitionMap.get(beanName).getBean();
}
public void setBean(String beanName, Object bean) {
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBean(bean);
beanDefinitionMap.put(beanName, beanDefinition);
}
}
这样,我们为了将对象的实例化交给容器管理的准备工作就完成了.
对象的实例化
使用容器对对象进行实例化,我们就需要使用反射来生成每一个类的具体对象.在BeanDefinition
中,我们就需要增加一些必须的字段
@SuppressWarnings("rawtypes")
public class BeanDefinition {
private Object bean;
private Class beanClass;
private String beanClassName;
public BeanDefinition() {
}
public Object getBean() {
return bean;
}
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();
}
}
}
这样,在BeanDefinition
中,通过增加beanClassName
字段,我们就可以在容器中初始化,实例化对象了.
BeanFactory
修改后如下:
public class BeanFactory {
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
public Object getBean(String beanName) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
String beanClassName = beanDefinitionMap.get(beanName)
.getBeanClassName();
return Class.forName(beanClassName).newInstance();
}
public void setBean(String beanName, String beanClassName) {
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanClassName(beanClassName);
beanDefinitionMap.put(beanName, beanDefinition);
}
}
这样,一个简单的容器就构建完了.
我们写个测试类来测试一下这个容器
class BeanFactoryTest {
@Test
void test() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
BeanFactory bc = new BeanFactory();
bc.setBean("hello", "com.zhangt.test.HelloWorldService");
HelloWorldService hwService = (HelloWorldService)bc.getBean("hello");
hwService.show();
}
}
输出为
this is a simple test for IOC form
说明容器是可以使用的.
这一章我们完善了之前的简单容器,使其成为一个可用的,具有解耦功能的框架,但是这个框架中还是缺少很多功能,例如,我们没有办法将对象的字段属性给注入进去,我们将在下一章来解决这个问题
网友评论