说明:Spring 的bean容器相当于一个Map<String, Object> beanMap,key为id,value为该class对应的实例对象。故模拟时,把所有的bean都放在一个map中
1、自定义一个简单的 beans.xml 模拟spring的beans.xml
<beans>
<bean id="u" class="com.wxx.dao.impl.UserDaoImpl" />
<bean id="userService" class="com.wxx.service.UserSerivce">
<property name="userDao" bean="u" />
</bean>
</beans>
2、BeanFactory模拟spring里的BeanFactory
public interface BeanFactory {
Object getBean(String name);
}
3、重点:模拟ClassPathXmlApplicationContext对xml文件处理的过程,通过反射实例化一个对象放到map中,对于他的property属性,通过反射调用set方法,给他装配相应的属性。
package com.wxx.spring;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
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.JDOMException;
import org.jdom2.input.SAXBuilder;
public class ClassPathXmlApplicationContext2 implements BeanFactory {
// bean容器
private Map<String, Object> beanMap = new HashMap<String, Object>();
// 构造方法
public ClassPathXmlApplicationContext2() throws JDOMException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
SAXBuilder builder = new SAXBuilder();
Document document = builder.build(this.getClass().getResourceAsStream("/beans.xml"));
Element rootElement = document.getRootElement();
List<Element> beanList = rootElement.getChildren();
for(Element element : beanList) {
String id = element.getAttributeValue("id");
String classStr = element.getAttributeValue("class");
// 根据类名实例化一个对象
Class clazz = Class.forName(classStr);
Object instance = clazz.newInstance();
// 到第二个循环时:key="userService", value=userService实例对象
beanMap.put(id, instance);
// 获取当前 bean的子元素
List<Element> beanPropertyList = element.getChildren();
if(beanPropertyList != null && beanPropertyList.size() != 0) {
for(Element element2 : beanPropertyList) {
String nameStr = element2.getAttributeValue("name"); // "userDao"
String beanStr = element2.getAttributeValue("bean"); // "u"
// 从beanMap中获取已经存在的bean
Object beanObj = beanMap.get(beanStr); // userDao
//根据name获取set方法
String setMethodStr = "set" + nameStr.substring(0, 1).toUpperCase() + nameStr.substring(1);
System.out.println("拼装的set方法:" + setMethodStr);
Method method = instance.getClass().getMethod(setMethodStr, beanObj.getClass().getInterfaces()[0]);
// 调用userService的 setUserDao方法,传递参数为 userDao
method.invoke(instance, beanObj);
}
}
}
}
@Override
public Object getBean(String name) {
return beanMap.get(name);
}
}
4、User,UserService,UserDao等省略
5、测试
package com.wxx.service;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.jdom2.JDOMException;
import org.junit.Test;
import com.wxx.model.User;
import com.wxx.spring.BeanFactory;
import com.wxx.spring.ClassPathXmlApplicationContext2;
public class UserSerivceTest {
@Test
public void testAdd() throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, JDOMException, IOException {
BeanFactory factory = new ClassPathXmlApplicationContext2();
// 获取userservice,此时,已经自动装配 userDao完成
UserSerivce service = new UserSerivce();
User u = new User();
// 调用service的add方法
service.add(u);
}
}