您的位置:首页 > 编程语言 > Java开发

【实例】模拟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()");
}
}

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来获得对象了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: