spring进阶三
2015-09-28 14:47
441 查看
简单配置,反射
上篇博文容器初始化时,使用new的方式来实力化对象,这篇博文我们利用配置文件+反射实力化对象,进一步封
装降低容器和组件的耦合度。下面我们先看一下配置文件。
[html] view
plaincopyprint?
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="dao" class="com.tgb.container.dao.impl.Dao4MySqlImpl" />
<bean id="service" class="com.tgb.container.service.impl.ServiceImpl" />
</beans>
看到上面的配置文件,除了命名空间没有,和Spring的配置文件已经很像了,下面我们就使用dom4j或jdom来读取
配置文件,并将配置文件中配置类利用反射实例化。本实例我们使用的jdom,大家也可以使用dom4j试一下。下面我
们看一下读取配置文件的代码:
[java] view
plaincopyprint?
public interface BeanFactory {
Object getBean(String id);
}
[java] view
plaincopyprint?
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
import com.tgb.container.dao.Dao;
import com.tgb.container.service.Service;
/**
* 从类路径加载配置文件
*
* @author liang
*
*/
public class ClassPathXmlApplicationContext implements BeanFactory {
// 用于存放Bean
private Map<String, Object> beans = new HashMap<String, Object>();
public ClassPathXmlApplicationContext(String fileName) {
this.readXML(fileName);
}
// 解析xml文件,通过反射将配置的beasn放到container中,并实现依赖注入
private void readXML(String fileName) {
// 创建SAXBuilder对象
SAXBuilder saxBuilder = new SAXBuilder();
// 读取资源,获得document对象
Document doc;
try {
doc = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream(fileName));
// 获取根元素
Element rootEle = doc.getRootElement();
// 从根元素获得所有的子元素,建立元素集合
List listBean = XPath.selectNodes(rootEle, "/beans/bean");
// 遍历根元素的子元素集合,扫描配置文件中的bean
for (int i = 0; i < listBean.size(); i++) {
Element bean = (Element) listBean.get(i);
// 获取id属性值
String id = bean.getAttributeValue("id");
// 获取class属性值
String clazz = bean.getAttributeValue("class");
// 反射,实例化
Object o = Class.forName(clazz).newInstance();
beans.put(id, o);
}
// 依赖管理,这里还不灵活,但是原理是一样的
Service service = (Service) beans.get("service");
Dao dao = (Dao) beans.get("dao");
// 依赖注入,Service实现依赖dao的实现
service.setDao(dao);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 查找组件
*
* @param id
* @return
*/
@Override
public Object getBean(String id) {
return beans.get(id);
}
}
看到上面的代码,我们发现读取配置文件的方法中包含了反射,代码的可读性太差,并且对面向对象的封装不够彻
底,下面我们将bean的实例化以及依赖注入进行进一步的封装。
封装bean的实例化
为了做进一步的封装,我们将配置文件的属性封装成一个javabean,为了存放我们的属性值。如下所示:[java] view
plaincopyprint?
public class BeanDefinition {
private String id;
private String className;
public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}
现在我们就可以把bean的实例化做进一步的封装了。
[java] view
plaincopyprint?
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;
import com.tgb.container.dao.Dao;
import com.tgb.container.service.Service;
/**
* 容器
*
* @author liang
*
*/
public class ClassPathXmlApplicationContext implements BeanFactory {
// 用于存放Bean
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
// 用于存放Bean的实例
private Map<String, Object> sigletons =new HashMap<String, Object>();
public ClassPathXmlApplicationContext(String fileName) {
this.readXML(fileName);
this.instanceBeans();
this.injectObject();
}
/**
* 依赖注入,为bean对象的属性注入值
* 这里还不灵活,但是原理是一样的
*/
private void injectObject() {
Service service = (Service) this.sigletons.get("service");
Dao dao = (Dao) this.sigletons.get("dao");
//依赖注入,Service实现依赖dao的实现
service.setDao(dao);
}
/**
* 完成bean的实例化
*/
private void instanceBeans() {
for(BeanDefinition beanDefinition : beanDefines){
try {
if(beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())){
sigletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance() );
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 读取xml配置文件
*/
private void readXML(String fileName) {
// 创建SAXBuilder对象
SAXBuilder saxBuilder = new SAXBuilder();
try {
// 读取资源,获得document对象
Document doc = saxBuilder.build(this.getClass().getClassLoader()
.getResourceAsStream(fileName));
// 获取根元素
Element rootEle = doc.getRootElement();
// 从根元素获得所有的子元素,建立元素集合
List listBean = XPath.selectNodes(rootEle, "/beans/bean");
// 遍历根元素的子元素集合,扫描配置文件中的bean
for (int i = 0; i < listBean.size(); i++) {
Element bean = (Element) listBean.get(i);
// 获取id属性值
String id = bean.getAttributeValue("id");
// 获取class属性值
String clazz = bean.getAttributeValue("class");
BeanDefinition beanDefine = new BeanDefinition(id,clazz);
// 将javabean添加到集合中
beanDefines.add(beanDefine);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取bean实例
*/
@Override
public Object getBean(String beanName) {
return this.sigletons.get(beanName);
}
}
我们知道容器不仅负责创建对象,而且可以管理对象的依赖关系,管理对象的生命周期等等。我们仅实现了容器
灵活创建对象的部分,依赖注入部分是由我们手动注入的。 对象的依赖关系还不灵活,但是我们已经能够看到IoC的
影子了,只是形似,还没有达到神似的目标。
相关文章推荐
- 深入浅出RxJava(四:响应式安卓开发)
- 深入浅出RxJava(三:响应式的好处)
- java 线程的状态转换
- RxJava的基础使用(二)
- 深入浅出RxJava(一:基础篇)
- JAVA实现异步调用实例代码
- JavaBean转换为XML的源码
- Struts2 三、指定Struts2处理的请求后缀
- Struts2 三、指定Struts2处理的请求后缀
- java 去除字符串的换行符
- Map用法
- 学习maven的使用(maven在eclipse中的使用)(一)
- spring mvc 获取到request response @ModelAttribute
- eclipse中egit插件使用--升级版
- leetcode:Interleaving String 使用动态规划求解的java源代码
- eclipse中使用axis2插件发布服务(WebService)和生成客户端(Client)及axis2插件的使用
- Java maven国内镜像
- Java基础学习总结----数据类型和运算符
- An unexpected error has been detected by Java Runtime Environment
- Spring MVC 中的 forward 和 redirect