目录
【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八)
【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主动查找和控制反转(九)
【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
博文【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八),我们为了去掉接口对具体实现的依赖关系,封装了一个特别简陋的容器。
博文【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主动查找和控制反转(九),我们利用控制反转,去掉了组件对容器的依赖。
博文【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十),我们实现了读取配置文件,以及容器创建对象的灵活,简单的IoC。
这篇博文的目标是不仅形似Spring,而且要神似Spring,进一步封装对象的依赖关系。
我们知道Spring框架,不仅可以根据配置创建对象,而且可以根据配置创建对象之间的依赖关系。对象之间的依
赖关系怎么配置呢,那我们先看一下配置文件。
<?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"> <property name="dao" ref="dao"></property> </bean> </beans>
我们发现配置文件中多了两个属性:property和ref,表达了Service需要依赖Dao的关系,所以我们需要将dao注入
给Service,怎么做呢?我们只需要像存储bean一样建立一个JavaBean即可:
public class PropertyDefinition { private String name; private String ref; public PropertyDefinition(String name, String ref) { this.name = name; this.ref = ref; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getRef() { return ref; } public void setRef(String ref) { this.ref = ref; } }
有了javabean,我们就只需要专注于怎么为bean对象的属性注入值。我们可以利用内省来操作Bean类属性、事
件。一般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器
(PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反
射机制来调用这些方法,最后将引用对象注入到属性中。
import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; 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; /** * 容器 * * @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() { for (BeanDefinition beanDefinition :beanDefines) { Object bean = sigletons.get(beanDefinition.getId()); if(bean != null){ try { // 通过Introspector取得bean的定义信息,之后再取得属性的描述信息,返回一个数组 PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition propertyDefinition:beanDefinition.getPropertys()){ for(PropertyDescriptor properdesc: ps){ if(propertyDefinition.getName().equals(properdesc.getName())){ // 获取属性的setter方法,private Method setter = properdesc.getWriteMethod(); if(setter != null){ Object value = sigletons.get(propertyDefinition.getRef()); // 允许访问私有方法 setter.setAccessible(true); // 把引用对象注入到属性 setter.invoke(bean, value); } break; } } } } catch (Exception e) { e.printStackTrace(); } } } } /** * 完成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++) { // 将根元素beans下的bean子元素作为一个新的子根元素 Element elementBean = (Element) listBean.get(i); //获取id属性值 String id = elementBean.getAttributeValue("id"); //获取class属性值 String clazz = elementBean.getAttributeValue("class"); BeanDefinition beanDefine = new BeanDefinition(id,clazz); // 获取子根元素bean下的所有property子元素 List listProperty = elementBean.getChildren("property"); // 遍历子根元素的子元素集合(即遍历property元素) for (int j = 0; j < listProperty.size(); j++) { // 获取property元素 Element elmentProperty = (Element)listProperty.get(j); // 获取name属性值 String propertyName = elmentProperty.getAttributeValue("name"); // 获取ref属性值 String propertyref = elmentProperty.getAttributeValue("ref"); PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName,propertyref); beanDefine.getPropertys().add(propertyDefinition); } // 将javabean添加到集合中 beanDefines.add(beanDefine); } } catch (Exception e) { e.printStackTrace(); } } /** * 获取bean实例 */ @Override public Object getBean(String beanName) { return this.sigletons.get(beanName); } }
此时我们就可以把Service接口的set方法去掉了。
public interface Service { public void serviceMethod(); }
这里仅有部分代码,大家可以在下面链接中下载。
总结
经过四篇博文的重构,我们实现了一个Spring的雏形,它可以让我们更加深刻的认识Spring的原理,对我们更加
深入的学习Spring埋下了伏笔。
相关推荐
我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC...【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)
【SSH进阶之路】一步步重构容器实现Spring的IoC——从一个简单的容器开始(八) 【SSH进阶之路】一步步重构容器实现Spring的IoC——解决容器对组件的“侵入式”管理的两种方案--服务定位器和IoC容器(九) 【SSH进阶之路...
SSH框架,全称为Spring、Struts和Hibernate,是Java企业级开发中常用的一种开源框架组合。这个框架集合提供了模型-视图-控制器(MVC)的架构模式,用于构建高效、可扩展且易于维护的Web应用程序。以下是SSH框架各...
- **struts-spring-plugin.jar的内部实现**:该插件通过拦截器来获取Spring容器中的Action对象,并将其传递给Struts2框架处理。 #### 十、Spring的事务管理 - **声明式事务管理(基于配置方式实现事务控制)**:...
### Struts2+Hibernate+Spring三大框架技术 #### Struts2 框架技术 **MVC概述** MVC(Model-View-Controller)是一种软件架构设计模式,它将应用程序分为三个基本部分:模型(Model)、视图(View)与控制器...
SSH框架是Java Web开发中常用的三大框架整合,包括Spring、Struts和Hibernate。Spring作为核心容器,负责管理对象和依赖注入;Struts处理MVC模式中的Controller层,负责请求分发;Hibernate则作为持久化层,用于...
Struts+Spring+Hibernate实现上传下载 本文将围绕SSH文件上传下载的主题,向您详细讲述如何开发基于SSH的Web程序。SSH各框架的均为当前最新版本: •Struts 1.2 •Spring 1.2.5 •Hibernate 3.0 本文...
JAVA SSH 框架,全称为Struts + Spring + Hibernate,是Java开发中常见的企业级应用框架组合。这个框架集合了三个独立的组件,分别针对应用程序的不同层面,以实现高效、解耦和可维护的软件架构。 Struts是MVC...
首先,Spring是一个全面的企业级应用框架,它提供依赖注入(DI)、面向切面编程(AOP)、数据访问、事务管理等多种功能,极大地简化了Java应用的开发。Spring Boot则是Spring的衍生版,旨在简化Spring应用的初始搭建和...
SSH 框架,全称为 Spring、Struts 和 Hibernate,是Java EE开发中常用的一套经典框架组合。这个框架集合提供了完整的三层架构解决方案,用于构建高效、可维护且可扩展的企业级应用程序。 首先,让我们详细了解这三...
在《hibernate-spring-struts整合手册》中,作者Hantsy Bai旨在展示如何结合strutsMVC框架、Spring中间层以及Hibernate后端技术,共同构建一个名为“MyUsers”的简单三层架构Web应用程序。此程序将实现基本的CRUD...
在Java Spring框架的学习过程中,SSH(Struts + Spring + Hibernate)的整合是一个重要的环节。本课程主要介绍如何使用注解的方式来进行SSH整合,这种方式可以减少XML配置的复杂度,并且更符合现代软件开发的趋势。 ...
SSH框架,即Struts、Spring和Hibernate的组合,是一种广泛应用于Java Web开发的开源框架,特别适合构建复杂的、企业级的管理系统。SSH框架的优势在于其模块化设计,能够实现业务逻辑、数据访问和视图展示的有效分离...
在IT行业中,SSH(Spring、Struts、Hibernate)是一个经典的Java Web开发框架组合,用于构建高效、可维护的Web应用程序。在这个"ssh-使用注解"的项目中,重点是利用注解来简化代码和提高代码的可读性。下面我们将...
- **SSH框架**:SSH是Struts2、Spring和Hibernate三个开源框架的首字母缩写。这些框架被广泛应用于Java Web开发中,用于构建高性能的企业级应用。 - **Struts2**:负责处理用户的请求,提供MVC模式的支持,简化Web...
人员配备、开发效率等都非常重要,但是开发效率包含很多,如:代码质量(扩展性、重构性等),但是这些都是建立在规范的代码之上来进行,在一个团队中,每个开发者都有自己的习惯方式来进行代码的编写,例如(ssh文件名举例)...
3. **配置【tutorial-web】中的Spring、Hibernate和Struts2框架**:实现Web层的功能,包括页面显示和数据交互。 4. **实现简单的页面操作**:使用LigerUI框架完成基本的增删改查功能。 5. **重构Maven依赖**:优化...
Spring则是一个全面的企业级应用框架,支持IOC(控制反转)和DI(依赖注入)。 4. **Spring全家桶**:除了Struts2和Hibernate,还熟练使用SpringMVC、JPA、SpringData、SpringSecurity、Shiro、JBPM和MyBatis。...
而Spring框架则提供了一个轻量级的容器,并且对Java企业版(J2EE)的各种服务进行了抽象和封装,为Java企业级应用开发提供了全面的编程和配置模型。 通过阅读这本书,开发者可以了解到如何在企业级开发中有效地应用...