经过一天的补习,学习文件加载,java反射,JDom等知识,到了晚上终于能够搭出一个基于配置文件的简单spring框架实现!

首先我们先看看这个问题:

下面是两副图左边是项目结构图,右边是UML图:

                   

正常情况下我们会按照上图一行一行的写代码:

其中UserService的代码是这样的

public class UserService {//实现dao层的一个实例对象private UserDAO userDAO=new UserDAOImpl();//userDAO的setter和getterpublic UserDAO getUserDao() {return userDAO;}public void setUserDAO(UserDAO userDAO) {this.userDAO = userDAO;}//添加用户public void add(User user) {if (userDAO == null)System.out.println("erro");else {userDAO.add(user);}}}

正像UML图所画的那样,UserService对User,UserDao,UserDAOImpl都有单向关联!

这里我们思考一下:

这仅仅是一个对象的操作,如果有TeacherService,狗Service,猫Service.........那么我们是不是每个都得实现service手动的调动Dao,DAOImpl,User等等,何其麻烦,

我们再注意看看:

1.Dao层是专门 与数据库交互的,里面有很多方法,而service是用来调用dao层的方法,他们之间唯一的联系就是在方法调用时,

Service层通过 private UserDAO userDAO=new UserDAOImpl();来实现与DAO层的耦合,我们知道程序设计讲究”高内聚低耦合“,

2.我们再看private UserDAO userDAO=new UserDAOImpl(); 这句是得到UserDao这个接口对象实例,并且这个实例是由new UserDAOImpl来决定,

我们知道,一个接口可以有很多实现类,这样写就是证明这个类中UserDAO的实例只能是UserDaoImpl的实例,不能使其他实现接口类的实例,那么这个类就具备重用的灵活性

既然这样,有没有一种方式能够降低这种耦合,提高灵活性呢,答案是spring


Spring思路

我们的service和UserDAOImpl没有任何的联系,而是通过一个配置文件来关联各个类之间的关系

1.我们看看beans.xml

<beans><bean id="u" class="com.spring.dao.impl.UserDAOImpl" /><bean id="userService" class="com.spring.service.UserService" ><property name="userDAO" bean="u"/></bean></beans>

  配置文件中又两个bean,所谓的bean就是java中的类,每个bean都有 id和class两个属性,id就是代表这个bean唯一标识,class就是这个类的(包+类)名

我们看到第二个bean是有<property>子节点的,<property>表明这个bean中时存在以其他bean作为参数的,

并且这个参数bean在这个类中实例对象名字为(userDAO),在所有beans中这个参数bean的id=u

2.加载beans.xml

我们先定义一个容器,通常是一个Map类型的容器,按照<bean>顺序依次初始化每个bean对应的类的对象,并把这个对象,和对象的id存放到Map容器中

我们先来实现这个容器:

package com.spring.buildframework;import java.lang.reflect.Method;
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;public class ClassPathXMLApplicationContext {private static Map<String, Object> beans = new HashMap<String, Object>();public ClassPathXMLApplicationContext() {SAXBuilder sb = new SAXBuilder();try {Document doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));//获取根节点Element root=doc.getRootElement();//将根节点的下的孩子全部放到List中List allList= root.getChildren("bean");for(int i=0;i<allList.size();i++){Element sigElement=(Element)allList.get(i);//获取每个<bean>节点的id和class属性的值String id=sigElement.getAttribute("id").getValue();String clazz=sigElement.getAttribute("class").getValue();System.out.println(id+clazz);//根据获取的类名利用反射得到实例Class<?> demo=Class.forName(clazz);Object obj=demo.newInstance();//将id和类的实例放到beans中beans.put(id, obj);//判断该bean下是否存在property的子节点List propertyChild=sigElement.getChildren("property");for(int j=0;j<propertyChild.size();j++){//获取此bean下name和bean的属性 ,其中bean指的是配置文件中另一个beanElement propertyElement=(Element)propertyChild.get(j);String name=propertyElement.getAttributeValue("name");  //userDAOString bean=propertyElement.getAttributeValue("bean");    //u//拼接该bean(useDAO)的setter方法 setUserDAOString setterMethodName="set"+name.substring(0,1).toUpperCase()+name.substring(1);//调用setter方法是需要注入com.spring.dao.impl.UserDAOImpl类的 对象Object  fieldObj=beans.get(bean);//获取fieldObj对象的类的类型,Class<?> type=fieldObj.getClass().getInterfaces()[0];Method setterMethod=obj.getClass().getMethod(setterMethodName, type);setterMethod.invoke(obj,fieldObj);System.out.println(type);}}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}//提供给外界接口public static Object getBean(String id){return beans.get(id);}}

  我们只需要初始化这个类,我们就能获得上图中的容器,而容器中就包含着我们需要的所有配置了的类的对象!

这时我们的UserService:

package com.spring.service;import com.spring.dao.UserDAO;
import com.spring.dao.impl.UserDAOImpl;
import com.spring.model.User;public class UserService {private UserDAO userDAO;public UserDAO getUserDao() {return userDAO;}public void setUserDAO(UserDAO userDAO) {this.userDAO = userDAO;}public void add(User user) {if (userDAO == null)System.out.println("erro");else {userDAO.add(user);}}}

  请注意和之前的不同,我们不再实例化userDAO而是通过  ClassPathXMLApplicationContext 类调用其set方法来实例化。

其他类:

public class UserDAOImpl implements UserDAO {@Overridepublic void add(User user) {// TODO Auto-generated method stubSystem.out.println("user added successful");}}package com.spring.dao;import com.spring.model.User;public interface UserDAO {public void add(User user);
}package com.spring.model;public class User {private String username;private String age;
public String getUsername() {return username;
}
public void setUsername(String username) {this.username = username;
}
public String getAge() {return age;
}
public void setAge(String age) {this.age = age;
}}

  测试类:

public class ClassPathXMLApplicationContextTest {@Testpublic void test() {try {//   Class<?> demo=Class.forName("com.spring.dao.impl.UserDAOImpl");} catch (Exception e) {// TODO: handle exception}//得到转载容器类的实例ClassPathXMLApplicationContext test=new ClassPathXMLApplicationContext();                //从容器中获取userService对象UserService service=(UserService)ClassPathXMLApplicationContext.getBean("userService");User user=new User();                //执行方法service.add(user);fail("Not yet implemented");}}

  需要说明的是:我们得从容器中拿到UserService对象才能进行调用

就这样:通过xml文件配置的简单spring框架就实现了

顺便讲讲IOC和DI的概念:

IOC(Inverse Of Control):1>就在UseService中我们UserDaO的初始化不是掌握在我们自己手中,而是掌握在容器中

2>原来我们的程序写实现,现在依赖于抽象,也就是从实现具体的东西反转到接口(抽象上),给人的感觉是在控制接口而不是控制事项                            3>控制的实现在与接口而不是具体实现

DI(Dependency Inject)   :向bean中注入参数

转载于:https://www.cnblogs.com/fjsnail/p/3493344.html

自定义beans.xml文件实现Spring框架相关推荐

  1. 通过web.xml文件自动启动spring容器加载对应的配置文件

    在web开发中可以在web.xml文件中配置自启动的servlet或者web容器监听器,借助两者中的任何一者都可以完成启动spring web应用上下文的工作. 下面给出使用web监听器的方式来实现启 ...

  2. 一文详说idea创建自定义的xml文件,比如创建mybatisConfig.xml等

    文章目录 1. 文章引言 2. 解决问题 2.1 打开设置面板 2.2 输入配置信息 3. 测试xml文件 4. 文末总结 1. 文章引言 今天使用idea去创建userMapper.xml文件时,发 ...

  3. spirng的beans.xml文件报错

    问题如下图: 我在网上找了好多解决方案都不行,后来仔细看了看maven的pom.xml文件 如下: 发现我的依赖居然没有放在depenencys里面,于是我就试了试,就成功解决了! beans就不会爆 ...

  4. Maven中的自定义settings.xml文件

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  5. Redis:Spring框架下Redis的配置和调用,xml文件中redis的配置,redisTemplate的使用和jedis的使用

    老规矩了,再次重复一遍,配置XML文件为Spring框架所属,所使用的框架是Spring,非SpringBoot!!! Spring框架整合Redis并且使用 1.配置文件 <bean clas ...

  6. Spring 框架源码(二) 事务Transaction源码深度解析

    目录 一.基于xml形式开启Transaction 1. 创建数据库user 2. 创建一个maven 项目 3. 通过xml形式配置事务 1) 创建Spring 命名空间 2) 开启事务配置 3) ...

  7. spring 源码分析(1)-xml文件解析

    我们在最开始接触spring的时候,看到不少书spring入门的例子如下 ApplicationContext atx = new ClassPathXmlApplicationContext(&qu ...

  8. Spring框架IOC基础及XML的配置 第二章

    1 Spring概述 1.1 关于框架 框架的概念 框架:特指软件框架,它是我们在实际开发中解决项目需求的技术集合.运用框架可以大大简化代码的编写,缩短开发周期.同时,对后续负责项目维护的人员降低技术 ...

  9. spring入门:beans.xml不提示、别名、创建对象的三种方式

    spring的版本是2.5 一.beans.xml文件不提示 Location:spring-framework-2.5.6.SEC01\dist\resources\spring-beans-2.5 ...

最新文章

  1. 用python画爱心动图_编写Python爬虫抓取暴走漫画上gif图片的实例分享
  2. 青蛙跳台阶问题——剑指offer
  3. 【控制】《多智能体系统一致性与复杂网络同步控制》郭凌老师-第6章-Lurie 型动态网络的簇同步
  4. IE9浏览Flash页面时显示错位并不停地闪烁
  5. php amazon-s3_推荐亚马逊电影-一种协作方法
  6. dataearth可视域分析_谁不知道前期分析要用ARCGIS?我就是不会用啊
  7. 董明珠“不让加班了”!格力官宣:实行双休,取消加班
  8. Python MySQL 数据库
  9. 生产企业ERP流程是什么
  10. gensim提取一个句子的关键词_包含关键字 关键词提取 的文章 - 科学空间|Scientific Spaces...
  11. Win10 无线网卡驱动感叹号,显示错误代码56
  12. torrents.php怎么下载,PT站自动收藏免费种下载|PT Add Free Torrents To Bookmark脚本js插件_ - 极光下载站...
  13. html和jsp轮播,jsp页面、图片轮播
  14. pandas(四)pandas的拼接操作
  15. 数据库上机实验一、二
  16. struct结构体里能放函数吗?
  17. 基于变色龙认证树的云边端协同流式数据完整性验证模型
  18. 分享几个网址二维码生成api
  19. linux自动生成证书,Linux生成TLS证书
  20. 成熟的 XMOS 方案 ——「 XMOS USB Audio 」

热门文章

  1. 区域医疗移动医疗影像解决方案1-基于HTML5的PACS
  2. Ubuntu 16.04 安装 CUDA10.1 (解决循环登陆的问题)
  3. 解决chrome浏览器adobe flash player不是最新版本亲测可用的方法
  4. Windows10 解决“装了 .NET Framework 4.5.2/4.6.1/4.7.1等等任何版本 或版本更高的更新”问题
  5. ORA-00257归档日志写满的解决方法
  6. 即使对象属性显示在控制台日志中,也无法访问
  7. 使用Javascript / jQuery下载文件
  8. 如何获取查询生成器以字符串形式输出其原始SQL查询?
  9. HTML+CSS详解
  10. html 下拉列表返回值,jquery 根据后台返回值来选中下拉框 option 值