模拟Spring创建Bean和dom4j读取xml文件(视频学习-传智播客Spring2.5-03)
2011-12-29 19:26
483 查看
import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.ConvertUtils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; public class ItcastClassPathXMLApplicationContext { List<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>(); Map<String, Object> beans=new HashMap<String, Object>(); public ItcastClassPathXMLApplicationContext(String path) { // TODO Auto-generated constructor stub this.readXML(path); initialBeans(); injectBeans(); } private void injectBeans() { // TODO Auto-generated method stub //必须在注入之前先实例化好每一个Bean for(BeanDefinition bd:beanDefinitions){ Object bean=getBean(bd.getId()); if(bean!=null){ //注入依赖 try { //取得Bean的属性描述 PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDefinition pd:bd.getProperties()){ //pd中的name是否存在于Bean的属性中 for(PropertyDescriptor d:pdps){ if(d.getName().equals(pd.getName())){ //取得setter方法 Method setter=d.getWriteMethod();//private方法也会出错 Object value=null; if(setter!=null){ if(pd.getRef()!=null && !pd.getRef().equals("")){ value=getBean(pd.getRef()); }else{ value=ConvertUtils.convert(pd.getValue(), d.getPropertyType()); } } setter.setAccessible(true); //设置允许访问 setter.invoke(bean,value); break; } } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } private void initialBeans() { // TODO Auto-generated method stub for(BeanDefinition b:beanDefinitions){ if(b.getClassName()!=null&& !b.getClass().equals("")) try { beans.put(b.getId(), Class.forName(b.getClassName()).newInstance()); } catch (Exception e) { e.printStackTrace(); } } } /** * 读取xml配置文件 * @param path */ private void readXML(String path) { // TODO Auto-generated method stub SAXReader reader=new SAXReader();//创建读取器 URL url=getClass().getClassLoader().getResource(path); Document doc=null; try { doc=reader.read(url); //存放命名空间 Map<String,String> nsps=new HashMap<String,String>(); nsps.put("ns", "http://www.springframework.org/schema/beans"); XPath ePath=doc.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径 ePath.setNamespaceURIs(nsps); List<Element> eList=ePath.selectNodes(doc);//获取文档下所有bean节点 for(Element e:eList){ String id=e.attributeValue("id"); String className=e.attributeValue("class"); BeanDefinition bDefinition=new BeanDefinition(id, className); //读取property XPath pXPath=e.createXPath("ns:property");//当前元素 pXPath.setNamespaceURIs(nsps); List<Element> pros=pXPath.selectNodes(e); for(Element e2:pros){ String name=e2.attributeValue("name"); String ref=e2.attributeValue("ref"); String value=e2.attributeValue("value"); //System.out.println(name+" "+ref); PropertyDefinition pd=new PropertyDefinition(name, ref,value); bDefinition.getProperties().add(pd); } beanDefinitions.add(bDefinition); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Object getBean(String id){ return beans.get(id); } }
加入注解解析功能:
定义注解:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //表示使用的范围,编译器、运行期 @Retention(RetentionPolicy.RUNTIME) //注解可以加入的位置 @Target({ElementType.FIELD,ElementType.METHOD}) public @interface ItcastResource { String name() default ""; }
注解解析器做的事情。该方法加入到上面ItcastClassPathXMLApplicationContext中的构造函数中。
private void annotationInject() { // TODO Auto-generated method stub for(BeanDefinition bd:beanDefinitions){ Object bean=getBean(bd.getId()); if(bean!=null){ try { //取得所有的属性 PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); for(PropertyDescriptor pdesc:pdps){ //判断setter上是否存在注解 Method setter=pdesc.getWriteMethod(); if(setter!=null&& setter.isAnnotationPresent(ItcastResource.class)){ //取出注解的name属性 ItcastResource itRes=setter.getAnnotation(ItcastResource.class); Object value=null; if(itRes.name()!=null&&!itRes.name().equals("")){ value=getBean(itRes.name()); }else{ //取得属性的名称 value=getBean(pdesc.getName()); if(value==null){//按类型找 //遍历所有的bean for(String key:beans.keySet()){ //类型匹配 if(pdesc.getPropertyType().isAssignableFrom(beans.get(key).getClass())){ value=beans.get(key); break; } } } } setter.setAccessible(true); setter.invoke(bean, value); } } //取得字段 Field[] fields=bean.getClass().getDeclaredFields(); for(Field f:fields){ //是否存在注解 if(f.isAnnotationPresent(ItcastResource.class)){ ItcastResource itRes=f.getAnnotation(ItcastResource.class); Object value=null; if(itRes.name()!=null&&!itRes.name().equals("")){ value=getBean(itRes.name()); }else{ //取得属性的名称 value=getBean(f.getName()); if(value==null){//按类型找 //遍历所有的bean for(String key:beans.keySet()){ //类型匹配 if(f.getType().isAssignableFrom(beans.get(key).getClass())){ value=beans.get(key); break; } } } } f.setAccessible(true); f.set(bean, value); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
相关文章推荐
- 用dom4j读取配置文件来模拟spring的bean工厂
- 传智播客Spring2.5视频教程_Spring的三种实例化Bean的方式 1
- 传智播客Spring2.5视频教程_配置Spring管理的bean的作用域 1
- 传智播客Spring2.5视频教程_配置Spring管理的bean的作用域 2
- 传智播客Spring2.5视频教程_Spring管理的Bean的生命周期 2
- 传智播客Spring2.5视频教程_Spring的三种实例化Bean的方式 2
- 传智播客Spring2.5视频教程_Spring管理的Bean的生命周期 1
- Spring2.5学习1.2_模拟Spring容器对bean进行实例化
- 传智播客Spring视频教程学习笔记6
- 传智播客Spring视频教程学习笔记13
- Spring入门学习——使用Spring的FactoryBean创建Bean
- DOM4J 学习总结之 读取XML文件指定元素内容
- 传智播客Spring2.5视频教程_编码剖析Spring依赖注入的原理 4
- Spring2.5学习3.4_让Spring自动扫描和管理Bean
- 传智播客Spring2.5视频教程_编码剖析Spring依赖注入的原理 1
- 11_传智播客Spring2.5视频教程_用@Resource注解完成属性装配
- 15_传智播客Spring2.5视频教程_使用JDK中的Proxy技术实现AOP功能 2
- 传智播客Spring视频教程学习笔记3
- 传智播客Spring视频教程学习笔记14
- 传智播客-spring2.5(2)-模拟不采用框架情况下AOP的实现