- Spring IOC的实现是由工厂模式和Java的反射机制完成的。我们可以自己写一个beanfactory通过反射的方式获取bean。
- 新建一个bean.xml文件,使用dom4j解析xml文件,并且把bean放到一个map中。
bean.xml代码为:
<bean id="helloworld" class="hello.HelloWorld">
<property name="name" value="yuemingfei"/>
</bean>-
BeanFactory代码为:
<pre><code>
public class BeanFactory {private final Map<String, Object> map = new HashMap<String, Object>(); private void parseXml() throws Exception { SAXReader reader = new SAXReader(); InputStream in = ClassLoader.getSystemResourceAsStream("bean.xml"); Document document = reader.read(in); Element root = document.getRootElement(); String rootName = root.getName(); // google guava的Preconditions类的静态方法,判断参数是否和期望的一样 checkArgument("beans".equals(rootName), "获得的根节点不是bean"); @SuppressWarnings("unchecked") List<Element> list = root.elements(); for (Element bean : list) { if ("bean".equals(bean.getName())) { String id = bean.attributeValue("id"); String className = bean.attributeValue("class"); Object object = null; @SuppressWarnings("unchecked") Iterator<Element> it = bean.elementIterator(); Map<String, String> propertyMap = new HashMap<String, String>(); while(it.hasNext()){ Element propertyElement = it.next(); if("property".equals(propertyElement.getName())){ String propertyName = propertyElement.attributeValue("name"); String propertyValue = propertyElement.attributeValue("value"); propertyMap.put(propertyName, propertyValue); } } object = getInstance(className, propertyMap); map.put(id, object); } }
}
@SuppressWarnings("unchecked") private Object getInstance(String className, Map<String, String> map) throws Exception{ @SuppressWarnings("rawtypes") Class instance = Class.forName(className); Object obj = instance.newInstance(); Field[] fields = instance.getDeclaredFields(); for (Field field : fields) { String propertyName = field.getName(); String propertyValue = map.get(propertyName); String methodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1); Method method = instance.getMethod(methodName, String.class); method.invoke(obj, propertyValue); } return obj;
}
public Object getBean(String id) throws Exception{
parseXml();
return map.get(id);
}
}
</code></pre>
- HelloWorld类中只要一个name属性,除了getter,setter方法还有sayHello()方法。