【实例】模拟Spring
2015-12-24 12:22
597 查看
本实例来自于马士兵老师在Spring2.5中的视频教程
Spring中很典型的一个特征就是容器,此例子可以模拟Spring对Bean的管理,但不是真的完整的Spring,只是用来说明Spring在管理Bean到底是怎么做的
在Spring中我们常常使用bean.xml文件来对bean进行配置,所以在本例中需要对自己写的xml数据进行读取,读取方法
同时在Spring中使用factory来对bean进行管理,我们在这里先创建一个BeanFactory接口。
package com.xiao.spring;
public interface BeanFactory {
public Object getBean(String name);
}
之后写一个实现类——ClassPathXmlApplicationContext.java,这个实现类是用来读取xml表中的bean和其附带的property的,内容如下
package com.xiao.spring;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beans = new HashMap<String, Object>();
public ClassPathXmlApplicationContext() throws Exception {
// TODO Auto-generated constructor stub
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build("src/beans.xml");
Element root = document.getRootElement();
List<Element> elements = root.getChildren();
for(Element element : elements) {
String id = element.getAttributeValue("id");
String className = element.getAttributeValue("class");
System.out.println(id + " : " + className);
//此处使用newInstance的原因:newInstance()是实现IOC、反射、面对接口编程和依赖倒置等技术方法的必然选择
Object o = null;
o = Class.forName(className).newInstance();
beans.put(id, o);
for(Element propertyElement : (List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name");
String bean = propertyElement.getAttributeValue("bean");
//从刚刚放入beans中的bean对象列表中获取对象
Object beanObject = beans.get(bean);
//把当前的获取到的方法名前面加一个set,之后把原名字的首字母变成大写,这里就是让他调用到所需要的方法啦
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println("method name = " + methodName);
//获取到方法体
Method method = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
method.invoke(o, beanObject);
}
}
}
@Override
public Object getBean(String name) {
// TODO Auto-generated method stub
return beans.get(name);
}
}
在bean.xml文件中我是这样写的,定义了两个bean,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="com.xiao.dao.impl.UserDAOImpl">
</bean>
<bean id="userService" class="com.xiao.service.UserService">
<property name="userDAO" bean="u"/>
</bean>
</beans>
值得注意的是在userService这个Bean中的userDAO设置成了上面一个名叫u的bean(UserService中真的有userDAO这个属性的),这样当使用Factory的时候的时候就可以直接用getBean来获取到相应的的对象的。
附上UserService和UserDAOImpl这两个类的代码
package com.xiao.dao.impl;
import com.xiao.dao.UserDAO;
import com.xiao.model.User;
public class UserDAOImpl implements UserDAO {
@Override
public void save(User user) {
// TODO Auto-generated method stub
System.out.println("This is UserDAOImpl.save()");
}
}
我们在使用的时候就可以这样
<span style="white-space:pre"> </span>@Test
public void testAdd() throws Exception {
BeanFactory beanFactory = new ClassPathXmlApplicationContext();
UserService service = (UserService)beanFactory.getBean("userService");
UserDAO userDAO = (UserDAO) beanFactory.getBean("u");
service.setUserDAO(userDAO);
User u = new User();
service.add(u);
}
通过beanFactory中已经做好的bean来获得对象了
Spring中很典型的一个特征就是容器,此例子可以模拟Spring对Bean的管理,但不是真的完整的Spring,只是用来说明Spring在管理Bean到底是怎么做的
在Spring中我们常常使用bean.xml文件来对bean进行配置,所以在本例中需要对自己写的xml数据进行读取,读取方法
同时在Spring中使用factory来对bean进行管理,我们在这里先创建一个BeanFactory接口。
package com.xiao.spring;
public interface BeanFactory {
public Object getBean(String name);
}
之后写一个实现类——ClassPathXmlApplicationContext.java,这个实现类是用来读取xml表中的bean和其附带的property的,内容如下
package com.xiao.spring;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beans = new HashMap<String, Object>();
public ClassPathXmlApplicationContext() throws Exception {
// TODO Auto-generated constructor stub
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build("src/beans.xml");
Element root = document.getRootElement();
List<Element> elements = root.getChildren();
for(Element element : elements) {
String id = element.getAttributeValue("id");
String className = element.getAttributeValue("class");
System.out.println(id + " : " + className);
//此处使用newInstance的原因:newInstance()是实现IOC、反射、面对接口编程和依赖倒置等技术方法的必然选择
Object o = null;
o = Class.forName(className).newInstance();
beans.put(id, o);
for(Element propertyElement : (List<Element>)element.getChildren("property")) {
String name = propertyElement.getAttributeValue("name");
String bean = propertyElement.getAttributeValue("bean");
//从刚刚放入beans中的bean对象列表中获取对象
Object beanObject = beans.get(bean);
//把当前的获取到的方法名前面加一个set,之后把原名字的首字母变成大写,这里就是让他调用到所需要的方法啦
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
System.out.println("method name = " + methodName);
//获取到方法体
Method method = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
method.invoke(o, beanObject);
}
}
}
@Override
public Object getBean(String name) {
// TODO Auto-generated method stub
return beans.get(name);
}
}
在bean.xml文件中我是这样写的,定义了两个bean,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="u" class="com.xiao.dao.impl.UserDAOImpl">
</bean>
<bean id="userService" class="com.xiao.service.UserService">
<property name="userDAO" bean="u"/>
</bean>
</beans>
值得注意的是在userService这个Bean中的userDAO设置成了上面一个名叫u的bean(UserService中真的有userDAO这个属性的),这样当使用Factory的时候的时候就可以直接用getBean来获取到相应的的对象的。
附上UserService和UserDAOImpl这两个类的代码
package com.xiao.dao.impl;
import com.xiao.dao.UserDAO;
import com.xiao.model.User;
public class UserDAOImpl implements UserDAO {
@Override
public void save(User user) {
// TODO Auto-generated method stub
System.out.println("This is UserDAOImpl.save()");
}
}
package com.xiao.service; import com.xiao.dao.UserDAO; import com.xiao.dao.impl.UserDAOImpl; import com.xiao.model.User; /** * Service,只是业务逻辑 * @author 莫小雨 * */ public class UserService { private UserDAO userDAO = new UserDAOImpl(); public UserDAO getUserDAO() { return userDAO; } public void setUserDAO(UserDAO userDAO) { this.userDAO = userDAO; } public void add(User u) { this.userDAO.save(u); } }
我们在使用的时候就可以这样
<span style="white-space:pre"> </span>@Test
public void testAdd() throws Exception {
BeanFactory beanFactory = new ClassPathXmlApplicationContext();
UserService service = (UserService)beanFactory.getBean("userService");
UserDAO userDAO = (UserDAO) beanFactory.getBean("u");
service.setUserDAO(userDAO);
User u = new User();
service.add(u);
}
通过beanFactory中已经做好的bean来获得对象了
相关文章推荐
- 慕课网-Java入门第二季实战练习-答答租车系统
- JAVA设计模式之:责任链模式
- java 深入技术七(类的结构和反射)
- java常用正则表达式
- 阶梯问题
- Eclipse快捷键 10个最有用的快捷键
- Spring的事务传播属性
- 关闭eclipse自动弹出console功能
- Java中i++与++i的区别(效率分析)
- java中怎么使用json字符串
- Java中常见的日期操作(取值、转换、加减、比较)
- java数字转换为字符串,长度不够前面补0
- 【java基础】java通过相对路径读取文件
- Java integer to byte array
- 从头认识java-14.3 多维数组
- Java POI读取Excel 2003/2007/2010例子
- Convert short to byte[] in Java
- java 写入文件没有到磁盘问题
- Spring 学习笔记 (II) 之后处理器和Resource
- [分享]Java中Byte与基础类型之间的转换