模拟spring框架注入实现原理
这个我是参见了别人的一些东西,不是原创!
定义一些抽象的方法:
package com.huxin.springinject.dao; public interface Person {
public void save();
public void useAxe();
}
package com.huxin.springinject.dao; public interface Axe {
public void chop(); }
实现的一些方法:
package com.huxin.springinject.dao.impl; import com.huxin.springinject.dao.Axe;
import com.huxin.springinject.dao.Person; public class Chinese implements Person {
private Axe axe;
public Axe getAxe() {
return axe;
} public void setAxe(Axe axe) {
this.axe = axe;
} public void save() {
System.out.println("保存人的方法");
}
public void useAxe(){
axe.chop();
}
}
package com.huxin.springinject.dao.impl; import com.huxin.springinject.dao.Axe; public class StoneAxe implements Axe { @Override
public void chop() {
System.out.println("铁斧头砍柴真慢"); } }
这里是关键spring框架模拟的实现的一些原理!!!
package junit.test;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.commons.beanutils.ConvertUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
public class ApplicationContext {
List<BeanInformation> beansInformation = new ArrayList<BeanInformation>();
Map<String,Object> singleton = new HashMap<String,Object>(); public ApplicationContext(){};
public ApplicationContext(String filename){
readXml(filename);
initBean();
this.injectObject();
}
public void readXml(String filename){
SAXReader saxReader = new SAXReader();
Document document = null;
try{
//使用反射机制,通过文件名加载文件路径
URL xmlPath = this.getClass().getClassLoader().getResource(filename); //通过文件路径获得这个文件的document对象
document = saxReader.read(xmlPath); Map<String,String> nsMap = new HashMap<String,String>();
nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间 XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
xsub.setNamespaceURIs(nsMap);//设置命名空间 //获得所有路径下的节点
List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点
for(Element element : beans){
System.out.println(element.attributeValue("id"));
System.out.println(element.attributeValue("class")); BeanInformation beanInformation = new BeanInformation();
beanInformation.setId(element.attributeValue("id"));
beanInformation.setName(element.attributeValue("class")); XPath xref = element.createXPath("ns:property");//创建properties查询路径
xref.setNamespaceURIs(nsMap);//设置命名空间 List<Element> propertys = xref.selectNodes(element);
for(Element property : propertys){
PropertyInformation propertyInformation = new PropertyInformation();
propertyInformation.setName(property.attributeValue("name"));
propertyInformation.setRef(property.attributeValue("ref"));
propertyInformation.setValue(property.attributeValue("value"));
beanInformation.getPropertyInformation().add(propertyInformation);
}
beansInformation.add(beanInformation);
}
} catch(Exception e){
e.printStackTrace();
}
} public void initBean(){
for(BeanInformation beanInformation: beansInformation){
if(beanInformation.getName()!=null && !"".equals(beanInformation.getName())){
//通过反射机制,根据名字初始化这个类
try {
singleton.put(beanInformation.getId(), Class.forName(beanInformation.getName()).newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
} /**
* 关于注入的实现
*/
private void injectObject() {
for(BeanInformation beanInformation : beansInformation){
Object bean = singleton.get(beanInformation.getId());
if(bean!=null){
try {
PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyInformation propertyInformation : beanInformation.getPropertyInformation()){
for(PropertyDescriptor properdesc : ps){
if(propertyInformation.getName().equals(properdesc.getName())){
Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private
if(setter!=null){
Object value = null;
if(propertyInformation.getRef()!=null && !"".equals(propertyInformation.getRef().trim())){
value = singleton.get(propertyInformation.getRef());
}else{
value = ConvertUtils.convert(propertyInformation.getValue(), properdesc.getPropertyType());
}
setter.setAccessible(true);
setter.invoke(bean, value);//把引用对象注入到属性
}
break;
}
}
}
} catch (Exception e) {
}
}
}
} public Object getBean(String id){
return this.singleton.get(id);
}
}
package junit.test; import java.util.HashSet;
import java.util.Set; public class BeanInformation {
private String id;
private String name;
private Set<PropertyInformation> propertyInformation = new HashSet<PropertyInformation>();
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<PropertyInformation> getPropertyInformation() {
return propertyInformation;
}
public void setPropertyInformation(Set<PropertyInformation> propertyInformation) {
this.propertyInformation = propertyInformation;
}
}
package junit.test; public class PropertyInformation {
private String name;
private String ref;
private String value;
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;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
测试类:
package junit.test; import com.huxin.springinject.dao.Person; public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ApplicationContext("applicationContext.xml");
Person person = (Person)ac.getBean("chinese");
person.save();
person.useAxe();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="chinese" class="com.huxin.springinject.dao.impl.Chinese">
<property name="axe" ref="stoneAxe"/>
</bean>
<bean id="stoneAxe" class="com.huxin.springinject.dao.impl.StoneAxe"/>
</beans>
补充说明: 需要导入dom4j相应的辅助包和junit辅助包!
模拟spring框架注入实现原理的更多相关文章
- 采用dom4j和反射模拟Spring框架的依赖注入功能
Spring的依赖注入是指将对象的创建权交给Spring框架,将对象所依赖的属性注入进来的行为.在学习了dom4j后,其实也可以利用dom4j和反射做一个小Demo模拟Spring框架的这种功能.下面 ...
- Spring框架和MVC原理
Spring框架和MVC原理 目录 Spring框架 SpringMVC工作原理 参考资料 回到顶部 Spring框架 Spring当前框架有20个jar包,大致可以分为6大模块: Core Cont ...
- (转)编码剖析Spring依赖注入的原理
http://blog.csdn.net/yerenyuan_pku/article/details/52834561 Spring的依赖注入 前面我们就已经讲过所谓依赖注入就是指:在运行期,由外部容 ...
- Spring、Spring依赖注入与编码剖析Spring依赖注入的原理
Spring依赖注入 新建PersonIDao 和PersonDao底实现Save方法: public interface PersonIDao { public void save(); } pub ...
- 【Spring系列】- 手写模拟Spring框架
简单模拟Spring 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 前言 上次已经学习了 ...
- 模拟Spring依赖注入
通过读取xml文件,利用反射动态加载类和方法,其实就是spring的注入机制模拟,可以清晰的看出整个运行流程 1.配置文件 applicationContext.xml <beans> & ...
- Spring框架介绍和原理
SpringMVC框架介绍 1) Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面. Spring 框架提供了构建 Web 应用程序的全功 ...
- 简单模拟Spring的注入
主要就是读XML技术和反射技术. 在xml中读出相关配置信息,然后利用反射将其实例化为对象,并调用其构造方法,在实例化的过程中将属性注入实例. 实例化和属性注入这些操作都交给了框架,不再需要自己的去n ...
- spring @Autowired注入的原理
只知道如何用Autowired注解,知道可以替代set,get方法,很方便,却一直不知道,为什么可以代替 今天探索一下原因,所谓知其然还要知其所以然,才能理解的更好,记忆的更牢,才能转化为自己的知识. ...
随机推荐
- Hauntbox:用于控制你的自己主动化、电子创意家居的开源硬件盒子
Hauntbox 是一个开源硬件控制器,能够满足用随意传感器和控制器建立复杂的.自己主动化的萦绕在心头的电子项目. 它不须要焊接或者预先学什么知识.是全然可控制.并与Arduino插板兼容. 无需编程 ...
- ubuntu无法解析主机错误与解决的方法
今天在用命令行进行操作的时候,出现了无法解析主机的错误.google了一下,原来是hosts文件的问题.更改过来即可了 进入终端,输入 sudo gedit /etc/hosts.输入password ...
- 基于visual Studio2013解决C语言竞赛题之1053洗牌
题目 解决代码及点评 /* 功能:洗扑克牌.将54张牌分别编号为1,2,-,54号,并放在数组M中. 洗牌方法如下:产生[1,54]区间内的一个随机数K,将M[1]与M[K]交换: ...
- boost参考博客
http://blog.csdn.net/caimouse/article/category/1339053
- 最新OpenCV2.4.6与VS2010开发环境搭建
OpenCV2.4.6与VS2010开发环境搭建 由于很久没有用OpenCV了,之前用的是1.0版本和VC++6.0.现在已经到了VS2010+OpenCV2.4.6.安装使用之后,发现OpenCV的 ...
- 九度OnlineJudge之1020:最小长方形
题目描述: 给定一系列2维平面点的坐标(x, y),其中x和y均为整数,要求用一个最小的长方形框将所有点框在内.长方形框的边分别平行于x和y坐标轴,点落在边上也算是被框在内. 输入: ...
- 设计模式六大原则(2):里氏替换原则(Liskov Substitution Principle)
肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.事实上原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:假设对每 ...
- 怎样查看apk须要支持的Android版本号
假设有一个apk,须要知道他最低安装支持的Android版本号是什么,应该怎样查看呢? 直接将apk后缀名改为rar或者zip,拉出AndroidManifest.xml?不行,AndroidMani ...
- C++学习之路—引用(一)—基础知识
(根据<C++程序设计>(谭浩强)整理,整理者:华科小涛,@http://www.cnblogs.com/hust-ghtao转载请注明) 对一个数据可以建立一个“引用”,它的作用是为一个 ...
- ASP.NET - 多文件上传,纯代码,不使用插件
解决方案: 前段代码: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Mu ...