Spring是通过org.springframework.context.support.ClassPathXmlApplicationContext来实例化bean的对象,然后供其他的对象进行调用。这个例子就是模拟java实例化Bean的这个过程。
主要用相关技术:反射,XML,jdom。
操作步骤:
1, 构建能够读取xml配置文件,并且能够实例化Bean的类ClassPathXmlApplicationContext.java
(通过jdom读取配置文件信息,然后通过反射实例化类)
2, 准备Bean.xml配置文件,配置需要实例化类
3, 准备具体的实体类(Bean.xml配置的类)
4, 准备测试类,进行功能验证。
目的:
1, 更加深入了解Spring实例化的Bean的机制。
2, 扩展使用,不使用spring框架可以通过配置文件来决定需要实例化的类,而不用修改类本身。
废话少说,上代码了。
1, 创建ClassPathXmlApplicationContext.java, 为了便于扩展该类继承了BeanFactory接口
抽象一个BeanFactory的接口
package com.lch.spring; public interface BeanFactory { public Object getBean(String id); }
继承Bean的接口,创建ClassPathXmlApplicationContext 来模拟实例化Bean的过程
package com.lch.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; //模拟spring读取配置文件,生成对象实例的方式。 public class ClassPathXmlApplicationContext implements BeanFactory { private Map<String, Object> beans = new HashMap<String, Object>(); public ClassPathXmlApplicationContext() throws Exception, InstantiationException, IllegalAccessException, ClassNotFoundException { SAXBuilder sb = new SAXBuilder(); Document doc = sb.build(this.getClass().getClassLoader() .getResourceAsStream("beans.xml")); Element root = doc.getRootElement(); @SuppressWarnings("rawtypes") List list = root.getChildren("bean"); for (int i = 0; i < list.size(); i++) { Element element = (Element) list.get(i); String id = element.getAttributeValue("id"); String clazz = element.getAttributeValue("class"); Object o = Class.forName(clazz).newInstance(); beans.put(id, o); for(Element propertyElement : (List<Element>) element.getChildren("property")) { String name = propertyElement.getAttributeValue("name"); String bean = propertyElement.getAttributeValue("bean"); Object beanObject = beans.get(bean); String methondName = "set"+name.substring(0, 1).toUpperCase() + name.substring(1); Method m = o.getClass().getMethod(methondName, beanObject.getClass().getInterfaces()[0]); m.invoke(o, beanObject); // beanObject.getClass(). } } } @Override public Object getBean(String id) { return beans.get(id); } }
验证ClassPathXmlApplicationContext 执行效果。
2,创建一个bean.xml的文件,配置关联关系。
<beans> <bean id="u" class="com.lch.dao.impl.UserDAO" /> <bean id="userService" class="com.lch.service.UserService" > <property name="userDAO" bean="u"/> </bean> </beans>
3, 构建实体类,具体实现的方法
package com.lch.dao import com.lch.dao.UserDAO; import com.lch.model.User; public class UserDAO { @Override public void save(User user) { // TODO Auto-generated method stub System.out.println("User save!!!! user = "+user.getUsername() +" , password = "+user.getPassword() ); } }
package com.lch.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; } }
package com.lch.service; import com.lch.dao.UserDAO; import com.lch.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; } }