Spring简单的说就是作为控制反转的容器,看这篇文章前需要先搞懂“控制反转和依赖注入“这个设计模式

我们先来模拟Spring,实现用户添加的功能,新建WEB项目”Spring_0100_AbstractOrientedProgramming“,新建包”com.bjsxt.model“,创建一个User实体

package com.bjsxt.model;

public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

User实体

新建包”com.bjsxt.dao“,创建操作用户的接口"UserDAO",针对接口编程的好处是,接口的实现类可以无限拓展

package com.bjsxt.dao;
import com.bjsxt.model.User; public interface UserDAO {
public void save(User user);
}

UserDAO

新建包”com.bjsxt.dao.impl“,创建一个接口的实现类”UserDAOImpl“,用一个输出模拟保存成功

package com.bjsxt.dao.impl;

import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User; public class UserDAOImpl implements UserDAO { public void save(User user) {
//Hibernate
//JDBC
//XML
//NetWork
System.out.println("user saved!");
} }

UserDAOImpl

新建包”com.bjsxt.service“,新建类”UserService“,有一个”UserDAO“类型的属性,并且有对应的getter和setter方法,还有一个add方法调用UserDAO的save方法实现用户添加

package com.bjsxt.service;
import com.bjsxt.dao.UserDAO;
import com.bjsxt.dao.impl.UserDAOImpl;
import com.bjsxt.model.User; public class UserService {
private UserDAO userDAO; public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
}

UserService

按照传统方式,我们应该是在UserService中自己实例化UserDAO属性,但是现在这一切都交给Spring来完成,它会帮我们实例化,并且通过UserServcie的setter方法给UserDAO属性赋值。我们需要将对象写到配置文件里,然后Spring会读取配置文件,在运行时动态生成对象供我们调用

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

保存对象的XML文件

新建包”com.bjsxt.spring“,创建模拟Spring的接口”BeanFactory“和"ClassPathXmlApplicationContext"

package com.bjsxt.spring;

public interface BeanFactory {
public Object getBean(String id);
}

BeanFactory

package com.bjsxt.spring;

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 implements BeanFactory { private Map<String , Object> beans = new HashMap<String, Object>(); //IOC Inverse of Control DI Dependency Injection
public ClassPathXmlApplicationContext() throws Exception {
SAXBuilder sb=new SAXBuilder(); Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); //�����ĵ�����
Element root=doc.getRootElement(); //��ȡ��Ԫ��HD
List list=root.getChildren("bean");//ȡ����Ϊdisk������Ԫ��
for(int i=0;i<list.size();i++){
Element element=(Element)list.get(i);
String id=element.getAttributeValue("id");
String clazz=element.getAttributeValue("class");
Object o = Class.forName(clazz).newInstance();
System.out.println(id);
System.out.println(clazz);
beans.put(id, o); for(Element propertyElement : (List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name"); //userDAO
String bean = propertyElement.getAttributeValue("bean"); //u
Object beanObject = beans.get(bean);//UserDAOImpl instance String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println("method name = " + methodName); Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
m.invoke(o, beanObject);
} } } public Object getBean(String id) {
return beans.get(id);
} }

ClassPathXmlApplicationContext

接下来用JUnit做单元测试,新建源文件夹"Test"存放测试代码,新建包”com.bjsxt.service“,创建测试类”UserServiceTest“

package com.bjsxt.service;
import org.junit.Test; import com.bjsxt.dao.UserDAO;
import com.bjsxt.model.User;
import com.bjsxt.spring.BeanFactory;
import com.bjsxt.spring.ClassPathXmlApplicationContext; public class UserServiceTest { @Test
public void testAdd() throws Exception {
BeanFactory applicationContext = new ClassPathXmlApplicationContext();
UserService service = (UserService)applicationContext.getBean("userService");
User u = new User();
u.setUsername("zhangsan");
u.setPassword("zhangsan");
service.add(u);
} }

测试类

运行,效果如图

看到了吗,UserService中的add方法需要调用UserDAO的实例方法save,但是并没有实例化UserDAO属性,而是交给了Spring来完成

具体项目文件如图

尚学堂Spring视频教程(一):模拟Spring的更多相关文章

  1. Spring再接触 模拟Spring

    项目分层: 1.最土的方法是直接写到main中去 2.分出model层 2.如下 4.在抽象一个对数据库的访问层(跨数据库实现) 面向抽象编程 User.java package com.bjsxt. ...

  2. Spring依赖注入 --- 模拟实现

    Spring依赖注入 --- 模拟实现 面向接口编程,又称面向抽象编程, 数据库如果发生更改,对应的数据访问层也应该改变多写几个实现,需要用谁的时候在service里new谁就可以了面向抽象编程的好处 ...

  3. [原]容器学习(一):动手模拟spring的IoC

    介绍 学习经典框架的实现原理以及设计模式在其实际中的运用,是非常有必要的,可以让我们更好进行面向对象. 本篇文章就来模拟Spring的IOC功能,明白原理后,可以更好的使用它,进而为进行面向对象提供一 ...

  4. 容器学习(一):动手模拟spring的IoC

    介绍 学习经典框架的实现原理以及设计模式在事实上际中的运用,是很有必要的,能够让我们更好进行面向对象. 本篇文章就来模拟Spring的IOC功能.明确原理后,能够更好的使用它,进而为进行面向对象提供一 ...

  5. 自己动手模拟spring的IOC

    我们这里是模拟spring,主要模拟spring中的IOC功能,所以在此我们一样要在service层中定义dao的实例,当然不用new出来,我们就通过spring的IOC把这里的dao层注入进来.不要 ...

  6. 尚学堂Spring视频教程(二):Spring控制反转

    用Spring来实现IOC 在上节中我们自定义了一个接口BeanFactory和类ClassPathXmlApplicationContext来模拟Spring,其实它们在Spring中确实是存在的, ...

  7. [JAVA教程] 2016年最新spring4框架搭建视频教程 【尚学堂】

    Spring4框架 主讲:邹波 类型:SSH 适合对象:学习完javase.数据库技术.jdbc者 Spring4.0作为一个广泛使用的开源框架,它由Rod Johnson创建.它是为了解决企业应用开 ...

  8. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

  9. 采用dom4j和反射模拟Spring框架的依赖注入功能

    Spring的依赖注入是指将对象的创建权交给Spring框架,将对象所依赖的属性注入进来的行为.在学习了dom4j后,其实也可以利用dom4j和反射做一个小Demo模拟Spring框架的这种功能.下面 ...

随机推荐

  1. javascript获取浏览器窗口大小

    var w=window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; var h= ...

  2. Windows下Nginx的安装与配置

    Nginx ("engine x") 是一款高性能的,轻量级的HTTP Web 服务器 和 反向代理服务器及电子邮件 IMAP/POP3/SMTP 代理服务器. Nginx 是由俄 ...

  3. input 边框颜色

    border 的属性 有三个 border:5px solid red; 如果上述值缺少一个没有关系,例如border:#FF0000;是允许的. 分别对应:border-width, border- ...

  4. SDWebImage

    SDWebImage 加载图片的流程 入口 setImageWithURL:placeholderImage:options: 会先把 placeholderImage 显示,然后 SDWebImag ...

  5. 前端学习 第三弹: JavaScript语言的特性与发展

    前端学习 第三弹: JavaScript语言的特性与发展 javascript的缺点 1.没有命名空间,没有多文件的规范,同名函数相互覆盖 导致js的模块化很差 2.标准库很小 3.null和unde ...

  6. aop配置

    前置通知 后置通知 环绕通知 异常通知 定义切面 aop-config 切入点 切面 通知 spring jdbc

  7. 解决Type 'UnityEngine.Component' does not support slicing

    unity从4.x升级到5.x后部分脚本的编译错误 将animation改成GetComponent.<Animation>()

  8. HTML5画布实现方法:

    我们可以在HTML中使用属性width和height来定义Canvas.但是实现Canvas的相关功能主要还依赖于Javascript实现,即HTML5 Canvas API.我们使用javascri ...

  9. Hyper-V端口映射

    有时候我们为了让局域网或外网用户直接远程访问或访问虚拟机里的服务,可以将实机端口直接映射到Hyper-V的虚拟机里面,省去很多麻烦. 下面是hyper-v共享IP端口映射一些常用命令共享IP端口映射一 ...

  10. Mac系统终端命令行不执行命令 总出现command not found解决方法

    配置过安卓开发环境,改过bash_profile这个文件,最后不知怎么的只有cd命令能执行,我猜测可能修改bash_profile文件后没有保存 导致的     保存命令是:  source .bas ...