spring的设计是面向接口(抽象)的
好处:灵活,可以更换不同的实现
模拟spring读取xml配置文件
beans.xml//可以看成是一个大的容器
<beans>
<bean id="u" class="com.dao.impl.UserDAOImpl"/>
<bean id="userService" class="com.service.UserService">
<property name="userDAO" bean="u"/>
//把userDAO装配(注入)到userService中
</bean>
</beans>
public interface BeanFactory
{
public Object getBean(String name);
}
public class ClassPathXmlApplicationContext implements BeanFactory
{
private Map<String,Object> beans = new HashMap<String,Object>();
public ClassPathXmlApplicationContext() throws Exception{
SAXBuilder builder = new SAXBuilder();
Document doc =
builder.build(Sample.class.getClassLoader().getResourceAsStream("beans.xml"));
//构造文档对象
Element root = doc.getRootElement();//获取根元素
List list = root.getChildren("bean");//取名字为bean的所有元素
for(int i=0;i<list.size();i++){
Element element = (Element)list.get(i);
String id = element.getAttributeValue("id");
String clazz = element.getChildText("class");
System.out.println(id+":"+clazz);
Object o = Class.forName(clazz).newInstance();
beans.put(id,o);
for(Element propertyElement:(List<Element>)element.getChild("property")){
String name = propertyElement.getAttributeValue("name");//userDAO
String bean = propertyElement.getAttributeValue("bean");//u
Object beanObject = beans.get(bean);//UserDAOImpl instance
String methodName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
System.out.println("method name = "+methodName);
Method m = o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]);
//根据方法名和参数获取方法(因为可能存在重载)
//参数是userDAOImpl实现的接口中的一个
m.invoke(o,beanObject);
//调用o对象的m方法,传入参数beanObject
}
}
}
public Object getBean(String name)
{
return beans.get(name);
}
}
public class UserServiceTest
{
@Test
public void testAdd() throws Exception
{
BeanFactory factory = new ClassPathXmlApplicationContext();
UserService service = new UserService();
//UserDAO userDAO = (UserDAO)factory.getBean("u");
//service.setUserDAO(userDAO);
User u = new User();
service.add(u);
}
}