通过一个小例子还模拟Spring的执行过程,由于还没有接触过Spring,所以仅仅是模拟,不敢说是原理,也仅仅是供自己理解。这是第一版,等接触过Spring之后,会对这篇文章进行修改,我还会回来的!
一 添加用户
假设有这样的一个需求,在系统中添加一个用户。首先我们需要创建一个用户类:
public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
添加操作由UserService类来完成:
public class UserService { public void add(User user) { 将user保存到数据库; } }
为了代码的灵活,应该将数据库操作由一个单独的类来完成;为了代码的灵活性,以适应不同的数据库类型(如mysql,oracle),所以数据库操作写成接口:
public interface UserDAO { public void save(User user); } public class SubUserDAO implements UserDAO { public void save(User user) { 将user保存到数据库中; } }
这个时候,UserService就应该是调用UserDAO的save()方法,所以UserService改写成:
public class UserService { private UserDAO userDAO = new SubUserDAO(); public void add(User user) { userDAO.save(user); } public UserDAO getUseDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } }
至此,添加用户的功能就完成了,我们使用了分层的思想,保证了代码的灵活性。
二 模拟Spring操作
但是在上面的代码中,如果用调用UserService去添加user,需要构造出UserDAO的一个实例,这样就把代码写死了。 如果我们能把生成UserService类交由一个工厂类去实现,工厂类在构造UserDAO的实例时,不是把代码写死,而是通过去读配置文件。那么这将极大的提高程序的灵活性!当我们的需求发生改变时,只需要修改配置文件中的内容。配置文件的内容如下:
<beans> <bean id="user" class="com.cxy.dao.SubUserDAO" /> <bean id="userService" class="com.cxy.service.UserService" > <property name="userDAO" bean="user"/> </bean> </beans>
在Spring中,这是通过IOC来完成的,我还不是很确切的了解IOC。我首先概要性的阐述模拟Spring的思想:
先说如果要构造一个UserSerice对象需要完成的工作:
1)构造出UserDAO的具体实例,UserDAO dao = new SubUserDAO();
2) 构造UserService的对象,service = new UserService();
3) 调用service.setUserDAO(dao);
通过配置文件来如何完成呢:
1)通过jdom或dom4j去读配置文件中的内容,获得每个的id和class属性;
2)class属性是一个类的全额限定名,通过反射机制,可以构造出对应类的实例object;
3)将该类放到一个map中,map.put(id,object);对应上面的配置文件,第一个生成一个SubUserDAO的对象,dao;第二个生成UserService的对象service;
4) 如果下面还有,获得其name和bean属性;通过name可以拼凑出setUserDAO(),bean对应的是要传递过去的参数dao-map.get("user");
5)通过反射机制获得setUserDAO()对应的Method对象method,method.invoke(service,dao);
搞定!!!
下面是代码的实现:
//定义工厂接口 public interface BeanFactory { public Object getBean(String id); }
具体的实现类:
public class ClassPathXmlApplicationContext implements BeanFactory { private Map beans = new HashMap(); //IOC Inverse of Control DI Dependency Injection public ClassPathXmlApplicationContext() throws Exception { /* 这段程序的执行过程是这样的: 1)获得包含的list,应该包含两个元素; 2)遍历list,分别取出id和class,通过反射机制生成class对应的实体类的对象,bean.put(id,object) 3)在上面遍历list,生成对象,放进map之后,遍历该下面的,取出name和bean, 其中name表示要执行的方法名称,bean该方法的参数 4)拼凑出该方法的名称,通过反射获得该方法对应的Method对象,执行之 */ List list = 获得每个; //遍历 for(int i=0;i对应SubUserDAO,第二个对应UserService; //把New出来的类放进beans中 beans.put(id, object); //如果下面有property属性的话 for(Element propertyElement : (List)element.getChildren("property")) { 获得name; 获得bean; //SubUserDAO instance Object beanObject = beans.get(bean); //拼凑出setUserDAO() String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1); //通过反射获得该方法对应的Method对象 Method m = object.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]); m.invoke(object, beanObject); } } } public Object getBean(String id) { return beans.get(id); } }
在客户端通过如下代码就可以获得UserService的实例:
BeanFactory factory = new ClassPathXmlApplicationContext(); UserService service = (UserService) factory.getBean("userService"); service.add(new User());
这就是传说中的依赖注入:依赖配置文件;通过反射机制构造出对象,注入到容器(map)中。
第一版就此结束,感觉小有收获吧。期待第二版急需完善。
相关推荐
<项目介绍> 功能点: 模拟商城,完整的购物流程、后端运营平台对前端业务的支撑,和对项目的运维,有各项的监控指标和运维指标...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
MyBatis可以与Spring集成,利用Spring的事务管理来控制转账过程中的事务边界。 7. **错误处理和日志记录**:程序中应包含适当的异常处理,确保在转账失败时能捕获并处理错误。同时,日志记录可以帮助追踪和排查问题...
本项目是一个基于Java技术实现的简单BBS(Bulletin Board System,公告板系统)论坛,旨在提供一个学习和参考的平台,帮助初学者和开发者了解如何构建基本的在线讨论社区。这里我们将深入探讨该项目的核心技术和实现...
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用!...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
在"自己实现的struts1框架 仅供参考"这个项目中,作者尝试重新创建了Struts1的核心功能,以供学习和研究之用。 首先,我们要理解Struts1的核心概念: 1. **Model**:模型层负责业务逻辑处理,通常与数据库交互。在...
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用!...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
【基于Javaweb的网上点餐系统】是一种利用Java Web技术实现的在线订餐平台,主要用于模拟实际餐厅的点餐流程,为用户提供方便快捷的网络订餐服务。该系统通常包括前台用户界面和后台管理界面,分别面向普通消费者和...
药店销售管理系统SSM(药品销售)是一个基于Spring、SpringMVC和MyBatis的Java Web应用,用于模拟和管理药店的药品销售业务。...然而,该系统仅供学习和参考,不能用于商业用途,使用时需注意版权问题。
在这个练习中,开发者将学习如何在Spring框架中应用AOP来实现特定的功能,而描述“spring的aop的练习,代码可供参考,仅是aop功能实现,没有优化”进一步强调了这个资源主要是为了演示AOP的基本用法,而不是追求性能...
在Spring框架中实现一个简单的登录功能,对于初学者来说是一个很好的起点,因为它涵盖了核心的控制器、模型、视图以及验证的基础知识。...这个基础示例仅供参考,帮助初学者理解Spring框架的基本工作原理。
仅供参考。 基于java,mysql,spring,vue的项目。 实现用户的登录,注册功能 实现考生的模拟投档功能 实现学校和专业的预测推荐功能 实现各大院校专业的招生信息查看功能 可选择查看全校/学院/专业查看最高分、最低...
# springboot-manager## 介绍基于SpringBoot + Thymeleaf + Layui + Apache Shiro + Redis + Mybatis Plus 的后台管理系统 支持菜单权限与...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
- 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------
# MaxMall分销系统 ## 前言 MaxMall电商分销系统致力于打造一套适合微信分销的电商平台,该系统模拟三级分销系统,采用三级分销多级分润...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
高级java笔试题 Author:Vension E-mail: 关于 本项目是一个专注于收集Github上(主要是Android,也包括Fultter,微信小程序,ReactNative,JS等)优秀的的开源...oAuth2.0全家桶实战,前后端分离模拟商城,完整的购物流
# 基于Netty的socket server ------ ## 介绍 使用Netty分别实现了三个Socket server和一个socket client: > * server1:9099 主要用来...下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
7. **注意事项**:该系统仅供学习参考,不建议直接用于商业环境,因为可能未考虑完整的安全性、性能优化以及合规性问题。 通过研究这个药店销售管理系统,学习者不仅可以掌握SSM框架的使用,还能了解到软件开发的...
【天下陶网络商城(实用).zip】是一个包含源码、毕设、课设资源的压缩文件,主要用于学习和参考,不适用于商业用途。...在使用过程中,应遵守“仅供学习参考,不得商用”的原则,尊重原创,合法合规地进行学习研究。
高性能计算和并行计算的最终项目2018年5月如果您喜欢我的作品,请随时单击右上角的星号或叉子以供将来快速参考。环境规格为了获得最佳兼容性,该程序仅需要非常基本的先决条件。 的OpenMPI / 3.0.0 Python / 2.7.11...