本模拟实现的功能:将如下xml文件中的bean加载进spring容器,同时将studentDao注入studentService中,最后通过getBean()获取bean
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="studentDao" class="com.zju.test.StudentDao"></bean>
<bean id="studentService" class="com.zju.test.StudentService" >
<property name="studentDao" ref="studentDao"/>
</bean>
</beans>
一、数据结构的定义:
Spring中用BeanDefinition数据结构封装数据
BeanDefinition类:
package com.zju.xiaoye.bean;
import java.util.ArrayList;
import java.util.List;
/**
* BeanDefinition 的定义类
*
* @author xiaoye
*
*/
public class BeanDefinition {
private String id; //bean id
private String className; //bean className
private List<PropertyDefinition> properties = new ArrayList<PropertyDefinition>(); //定义bean中property子节点
public BeanDefinition(String id, String className) {
this.id = id;
this.className = className;
}
public BeanDefinition() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<PropertyDefinition> getProperties() {
return properties;
}
public void setProperties(List<PropertyDefinition> properties) {
this.properties = properties;
}
}
而PropertyDefinition定义如下:
package com.zju.xiaoye.bean;
public class PropertyDefinition {
private String name; //name属性
private String ref; //ref属性
public PropertyDefinition(String name, String ref) {
this.name = name;
this.ref = ref;
}
public PropertyDefinition() {
}
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;
}
}
二、模拟容器的实现
模拟容器类MockSpringXmlApplicationContext主要的结构如下:
package com.zju.xiaoye.context;
import ......
public class MockSpringXmlApplicationContext {
//BeanDefinition类型的List
private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
//容器的主要数据结构beanDefinitionMap
private Map<String, Object> beanDefinitionMap = new HashMap<String, Object>();
/**
* MockSpringXmlApplicationContext构造函数
* 执行读取xml文件readXml(fileName);
* 初始化Beans方法initBeas();
* 实现依赖注入inject();
* @param fileName
*/
public MockSpringXmlApplicationContext(String fileName){
this.readXml(fileName);
this.initBeans();
this.inject();
}
/**
* 读取xml文件信息进行解析
* 并将bean节点加入beanDefines中
* @param fileName
*/
private void readXml(String fileName){
.......
}
/**
* 遍历beanDefines将bean加入map中
*/
private void initBeans(){
......
}
/**
* 根据set方法实现依赖注入
* 遍历beanDefines集合,对每个beanDefinition,实现property节点的注入功能
*/
private void inject(){
......
}
/**
* 根据id从容器中获取bean
* @param id
* @return
*/
public Object getBean(String id){
return beanDefinitionMap.get(id);
}
}
下面介绍主要的方法实现
1)readXml(String fileName):用dom4j来解析xml文件
private void readXml(String fileName){
SAXReader saxReader = new SAXReader();
Document document = null;
try {
document = saxReader.read(new File(fileName));
Element root = document.getRootElement();
for(Iterator rootIter = root.elementIterator("bean"); rootIter.hasNext();){
Element beanNode = (Element) rootIter.next();
BeanDefinition beanDefinition = new BeanDefinition(beanNode.attributeValue("id"), beanNode.attributeValue("class"));
for(Iterator beanIter = beanNode.elementIterator(); beanIter.hasNext();){
Element property = (Element) beanIter.next();
PropertyDefinition propertyDefinition = new PropertyDefinition(property.attributeValue("name"),property.attributeValue("ref"));
beanDefinition.getProperties().add(propertyDefinition);
}
beanDefines.add(beanDefinition);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2)initBeans()
private void initBeans(){
for(BeanDefinition bean : beanDefines){
if(bean.getClassName()!=null && !"".equals(bean.getClassName().trim())){
try {
beanDefinitionMap.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());//反射获取实例
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
3)inject()
private void inject(){
for(BeanDefinition beanDefinition : beanDefines){
Object bean = beanDefinitionMap.get(beanDefinition.getId());
if(bean!=null){
try {
PropertyDescriptor [] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
for(PropertyDefinition propertyDefinition : beanDefinition.getProperties()){
for(PropertyDescriptor propertyDesc : ps){
if(propertyDesc.getName().equals(propertyDefinition.getName())){
Method setter = propertyDesc.getWriteMethod();//获取属性的set方法
if(setter!=null){
Object value = beanDefinitionMap.get(propertyDefinition.getRef());
setter.setAccessible(true); //处理private
setter.invoke(bean, value);//把引用对象注入到属性
}
break;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
分享到:
相关推荐
以注解方式模拟Spring IoC AOP,了解Spring是如何实现的.
这是个模拟spring ioc的学习例子,是个java工程。有助于对aop和ioc的理解
简单模拟spring ioc技术,一个小demo,希望对您理解ioc有所帮助.
基于xml注册,简单模拟spring ioc容器。快速理解ioc容器
练习共三部分: 1、XML读取,用于配置文件读取 2、模拟SPRING IOC 3、模拟STRUTS
手写springIOC 通过jdom读取xml文件 适合新手使用。
经过我整理了,写好了详细的注释,开发环境是myeclipse,希望对spring初学者能有帮助,大家相互帮助,谢谢!
自己写了一个Spring IoC的模拟,有详细注释,可供刚入门学习spring的童鞋加深理解.
NULL 博文链接:https://lgd-java2eye.iteye.com/blog/759878
NULL 博文链接:https://justsee.iteye.com/blog/1298861
该工程主要是模拟spring中IOC功能,自己模拟实现了简单的依赖注入。导入执行时,只需将文件拷入到自己的工程中即可使用。
模拟实现__Spring的Ioc 1、Spring主要两个作用:实例化Bean,动态装配Bean。并将所有的bean放到spring容器中,调用时从容器中取。Spring容器就是一个bean的Map:private Map, Object> beans = new HashMap, Object>...
SpringIOC和AOP实现机制模拟,来自与网络。
主要介绍了使用Java注解模拟spring ioc容器过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
模拟spring ioc aop的功能,理解spring ioc 和 aop 的实现原理和机制。
模拟Spring IOC 自己实现依赖注入 自己的Spring 自己的代码模拟spring的依赖注入 自己写的 绝对独一无二
Spring IOC AOP MVC 简单例子
模拟spring框架的ioc功能,简单实用的实现,高效。
该代码主要用于spring IOC的实现(墨者革离),模拟一个城门叩问的编剧场景
模拟实现spring IOC AOP的例子,如果你是eclipse开发工具,解压直接导入就可以,别忘了,导入dom4j的jar包。