您的位置:首页 > 编程语言 > Java开发

模拟Spring的内部原理读取配置文件,实例化

2012-04-27 23:06 411 查看
先写一个xml文件:beans.xml

<beans>

<bean id="u" class="com.msb.dao.UserDAOImpl" />

<bean id="userService" class="com.msb.service.UserService" >

<property name="userDAO" bean="u"/>

</bean>

</beans>

这段代码的意图就是先声明一个id为u的bean,再声明一个id为userService的bean,同时,打算把u注入到userService当中,并成为它的userDAO属性。

实现这一环节,就需要一个类来完成这项工作,我们用ClassPathXMLApplicationContext来做。

先写一个接口:

public interface BeanFactory {

public Object getBean(String name);

}

通过这个接口,拿到bean实例

public class ClassPathXMLApplicationContext implements BeanFactory {

private Map<String,Object> beans = new HashMap<String,Object>();

public ClassPathXMLApplicationContext(){ //在构造方法中

SAXBuilder sb=new SAXBuilder();

Document doc;

try {

doc = sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml"));

Element root=doc.getRootElement(); //获取根元素HD

List list=root.getChildren("bean");//找到标签为bean的节点

for(int i=0;i<list.size();i++){ //找到每一个bean

Element element=(Element)list.get(i);

String id=element.getAttributeValue("id"); //拿到它的id

String clazz=element.getAttributeValue("class"); //拿到它的class

Object o = Class.forName(clazz).newInstance(); //根据class生成实例

beans.put(id, o); //将id,以及生成实例,放在map当中

//拿到name之后,把第一个字母大写,前面加上set,来调用set方法,这样,就不用我们写

//userSerivce.setUserDAO(userDAO);这句话了

for(Element propertyElement : (List<Element>)element.getChildren("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]);

m.invoke(o, beanObject); //调用setUserDAO方法

}

}

}catch (Exception e) {

e.printStackTrace();

}

}

@Override

public Object getBean(String name) {

return beans.get(name);

}

}

最核心的内容就是这些,然后我们用Junit4来做测试:

@Test

public void testAdd(){

BeanFactory factory = new ClassPathXMLApplicationContext();

UserService userSerivce = (UserService)factory.getBean("userService"); //拿到userSerivce实例,在实例化该对象的同时,通过它的构造方法,把userDAO注入了

User u = new User();

userSerivce.add(u);

/*虽然我们写的是userSerivce.add(u)这是业务逻辑

实际的处理方式是调用userSerivce.userDAO.add,而userDAO就是我们通过读取配置文件而注入的*/

//控制反转:原来是类自己控制,自己调用自己的setUserDAO,而现在由容器来控制。由容器来生成这个属性。

}

Okay,就是这样了。。Spring乍一看很难理解,但是如果我们看了它的内部原理,其实并不难。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: