【实例】模拟Spring

本实例来自于马士兵老师在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来获得对象了

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值