模拟Spring的IoC或DI

前提:要想模拟实现Spring的IoC,先要掌握的知识点,XML,jdom解析XML,还要知道反射,理解这些后就可以模拟实现Spring的IoC了。   在我们实际用Spring的时候,Spring容器帮我们管理所有的bean,以及相应的依赖注入,当然这里我们先不提事务,AOP什么的先。

实际开发中一般都是才用分层模式: dao层
package com.lbx.dao;

import com.lbx.model.User;

public interface UserDAO {
	public void save(User user);
}
 dao实现层
package com.lbx.dao.impl;

import com.lbx.dao.UserDAO;
import com.lbx.model.User;

public class UserDAOImpl implements UserDAO {

	public void save(User user) {
		System.out.println("a user saved!!!");
	}

}
 model层
package com.lbx.model;

public class User {
	
	private String username;
	private String password;
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}
 服务层(注意,在服务器我们使用依赖注入的形式比较多,提供相应的set方法,Spring的IoC很好的帮我们降低了代码间的耦合性)
package com.lbx.service;

import com.lbx.dao.UserDAO;
import com.lbx.model.User;

public class UserService {
	private UserDAO userDAO;  
	public void add(User user) {
		userDAO.save(user);
	}
	public UserDAO getUserDAO() {
		return userDAO;
	}
	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}
}
 现在的问题是我们怎么将服务层中要使用的Bean(userDAO)注入进去,Spring提供了BeanFactory帮我们产生bean
package com.lbx.spring;

/**
 * 模拟Spring的实现
 * @author Administrator
 *
 */
public interface BeanFactory {
	public Object getBean(String id);
}
 而现实中的Spring提供了一个类ClassPathXmlApplicationContext实现了BeanFactory接口(该类中用一个Map存放所有的bean,一个id对应一个bean)
package com.lbx.spring;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

public class ClassPathXmlApplicationContext implements BeanFactory {

	// 一个id对应一个bean
	private Map<String, Object> beans = new HashMap<String, Object>();

	public ClassPathXmlApplicationContext() throws Exception {
		// jdom解析XML
		SAXBuilder builder = new SAXBuilder();
		// 开始解析XML
		Document document = builder.build("beans.xml");
		// 获得根元素
		Element root = document.getRootElement();
		// 获取根元素下的所有子元素
		List lists = root.getChildren();
		// 遍历所有的子元素
		for (int i = 0; i < lists.size(); i++) {
			Element e = (Element) lists.get(i);
			String id = e.getAttributeValue("id");
			// 获得bean里面的class
			String class1 = e.getAttributeValue("class");
			// 利用反射获得对象的实例
			Object obj = Class.forName(class1).newInstance();
			System.out.println(id);
			System.out.println(class1);
			beans.put(id, obj);

			// 要是子元素中还有属性
			for (Element propertyElement : (List<Element>) e
					.getChildren("property")) {
				// 根据属性的name
				String name = propertyElement.getAttributeValue("name");
				// 获得要注入的bean的id
				String bean = propertyElement.getAttributeValue("ref");
				// 获得要注入bean的实例(Map中根据id)
				Object beanObject = beans.get(bean);
				// 生成相应的set方法
				String methodName = "set" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);
				System.out.println("set方法名:  " + methodName);

				Method m = obj.getClass().getMethod(methodName,
						beanObject.getClass().getInterfaces()[0]);
				m.invoke(obj, beanObject);
			}
		}

	}

	@Override
	public Object getBean(String id) {
		return beans.get(id);
	}

}
 下面就是测试代码
package com.lbx.service;

import org.junit.Test;

import com.lbx.model.User;
import com.lbx.spring.BeanFactory;
import com.lbx.spring.ClassPathXmlApplicationContext;

public class UserServiceTest {

	@Test
	public void testAdd() throws Exception {
		BeanFactory applicationContext = new ClassPathXmlApplicationContext();
		
		UserService service = (UserService)applicationContext.getBean("userService");
		
		User u = new User();
		u.setUsername("lbx");
		u.setPassword("123456");
		service.add(u);
	}

}
 

 

 

你可能感兴趣的:(DAO,spring,xml,bean,IOC)