目录
【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八)
【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主动查找和控制反转(九)
【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)(已更新)
上上篇博文【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八),我们为了去掉接
口对具体实现的依赖关系,封装了一个特别简陋的容器。
上篇博文【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主
动查找和控制反转(九),我们利用控制反转,去掉了组件对容器的依赖。
简单配置,反射
上篇博文容器初始化时,使用new的方式来实力化对象,这篇博文我们利用配置文件+反射实力化对象,进一步封
装降低容器和组件的耦合度。下面我们先看一下配置文件。
<?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试一下。下面我
们看一下读取配置文件的代码:
public interface BeanFactory { Object getBean(String id); }
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,为了存放我们的属性值。如下所示:
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的实例化做进一步的封装了。
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的
影子了,只是形似,还没有达到神似的目标。
下篇博文【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一),马
上送上。
相关推荐
我们从一个简单的容器开始,一步步的...【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十) 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理...【SSH进阶之路】一步步重构容器实现Spring的IoC——工厂+反射+配置文件实现IoC容器(十)
- **案例:测试IoC(set注入)**:通过set方法来注入依赖对象,例如,定义一个接口和其实现类,然后在配置文件中通过`<bean>`元素配置Bean并使用`property`子元素设置依赖对象。 - **案例:测试IoC(构造注入)**:...
标题 "idea14+maven+struts+spring+mybatis框架" 描述的是一个使用IntelliJ IDEA 14集成开发环境,结合Maven构建工具,以及SSH(Struts、Spring、Hibernate)经典企业级开发框架,并融入MyBatis持久层框架的项目。...
SSH2+MySQL论坛完整代码和数据库文件是一套基于SSH2(Spring、Struts2、Hibernate)框架和MySQL数据库实现的论坛系统。这个资源对于学习Java Web开发,特别是SSH2框架的实战应用非常有价值。SSH2是Java开发中常见的...
1. **配置文件**:包括Spring的bean配置文件(如`applicationContext.xml`)、Struts2的配置文件(如`struts.xml`)、Hibernate的配置文件(如`hibernate.cfg.xml`)等,这些文件定义了框架的运行规则和组件间的关联...
Spring框架作为核心的IoC(Inversion of Control)和AOP(Aspect-Oriented Programming)容器,负责管理应用对象的生命周期和依赖关系,提供事务管理、数据源管理等功能。在校园招聘网站中,Spring可能被用来处理...
Spring框架的核心功能是作为容器,它可以管理和装配应用中的对象,此外,Spring还提供了IoC和AOP能力,使得开发者能够更方便地进行技术整合,比如与Struts2、Hibernate一起构建SSH架构。通过Spring,可以实现组件的...
### JAVA之开发技术学习文档 —— SSH框架及WEB开发与性能优化 #### 一、Spring框架详解 **Spring框架概述** Spring是一个轻量级的Java开发框架,它为开发人员提供了一个灵活且强大的平台,用于构建高效、健壮的...
SSH框架,全称为Spring、Struts和Hibernate,是Java企业级开发中常用的一种开源框架组合。这个框架集合提供了模型-视图-控制器(MVC)的架构模式,用于构建高效、可扩展且易于维护的Web应用程序。以下是SSH框架各...
- **多配置文件实现**:可以在多个配置文件中分散配置信息。 - **通过注解实现action的零配置**:使用注解简化配置过程。 #### Hibernate 框架技术 **持久化、持久层** 持久化是指将内存中的数据保存到磁盘的过程...
提供了对Spring核心模块的说明,表单中action属性的相对、绝对路径问题,以及用SSH重构NetCTOSS项目模块的步骤。 通过以上知识点,我们可以看出Spring框架的核心能力,包括能够轻松地与其他技术如Struts2和...
**基于配置SSH2的网上商城**是一个典型的Java Web项目,主要使用了Spring、Struts2和Hibernate这三大框架,简称SSH2。这个项目适合于学习和实践Java Web开发,特别是对于那些正在准备毕业设计的学生来说,它提供了一...
JavaConfig 是 Spring 社区的产品,提供了配置 Spring IoC 容器的纯 Java 方法。它有助于避免使用 XML 配置,并提供了面向对象的配置、类型安全和重构友好等优点。 3. Spring Boot 有哪些优点? Spring Boot 有...
自2003年首次发布以来,Spring已经成为Java开发领域中最流行和广泛使用的框架之一。Spring以其轻量级、模块化的设计理念,以及对依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect-Oriented ...
在IT行业中,SSH(Struts2、Spring、Hibernate)被称为三大框架,它们是Java Web开发中的核心组件,常用于构建企业级应用。本项目"三大框架整合,与数据库相连,下载就能用"提供了SSH整合的一个实例,对于初学者来说...
JAVA SSH 框架,全称为Struts + Spring + Hibernate,是Java开发中常见的企业级应用框架组合。这个框架集合了三个独立的组件,分别针对应用程序的不同层面,以实现高效、解耦和可维护的软件架构。 Struts是MVC...
这样,Struts应用可以利用Spring的IOC容器来管理和配置Action,从而实现更灵活的控制流和更好的解耦。 **Spring的IOC和AOP** Spring框架的核心是控制反转(Inversion of Control,IOC),它通过XML配置文件或注解来...
SSH,全称Spring、Struts、Hibernate,是Java Web开发中的三大框架,它们组合在一起,构建了高效、灵活的企业级应用程序。在这个名为"SSH经典学习案例-宠物管理系统"的项目中,我们可以深入学习如何利用这些技术来...