模拟Spring创建Bean和dom4j读取xml文件(视频学习传智播客Spring2.503)

  1 import java.beans.Introspector;
2 import java.beans.PropertyDescriptor;
3 import java.lang.reflect.Method;
4 import java.net.URL;
5 import java.util.ArrayList;
6 import java.util.HashMap;
7 import java.util.List;
8 import java.util.Map;
9
10 import org.apache.commons.beanutils.ConvertUtils;
11 import org.dom4j.Document;
12 import org.dom4j.Element;
13 import org.dom4j.XPath;
14 import org.dom4j.io.SAXReader;
15
16
17 public class ItcastClassPathXMLApplicationContext {
18 List<BeanDefinition> beanDefinitions=new ArrayList<BeanDefinition>();
19 Map<String, Object> beans=new HashMap<String, Object>();
20 public ItcastClassPathXMLApplicationContext(String path) {
21 // TODO Auto-generated constructor stub
22 this.readXML(path);
23 initialBeans();
24 injectBeans();
25 }
26 private void injectBeans() {
27 // TODO Auto-generated method stub
28 //必须在注入之前先实例化好每一个Bean
29 for(BeanDefinition bd:beanDefinitions){
30 Object bean=getBean(bd.getId());
31 if(bean!=null){
32 //注入依赖
33 try {
34 //取得Bean的属性描述
35 PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
36 for(PropertyDefinition pd:bd.getProperties()){
37 //pd中的name是否存在于Bean的属性中
38 for(PropertyDescriptor d:pdps){
39 if(d.getName().equals(pd.getName())){
40 //取得setter方法
41 Method setter=d.getWriteMethod();//private方法也会出错
42 Object value=null;
43 if(setter!=null){
44 if(pd.getRef()!=null && !pd.getRef().equals("")){
45 value=getBean(pd.getRef());
46 }else{
47 value=ConvertUtils.convert(pd.getValue(), d.getPropertyType());
48 }
49 }
50 setter.setAccessible(true); //设置允许访问
51 setter.invoke(bean,value);
52 break;
53 }
54 }
55 }
56 } catch (Exception e) {
57 // TODO Auto-generated catch block
58 e.printStackTrace();
59 }
60
61 }
62 }
63 }
64 private void initialBeans() {
65 // TODO Auto-generated method stub
66 for(BeanDefinition b:beanDefinitions){
67 if(b.getClassName()!=null&& !b.getClass().equals(""))
68 try {
69 beans.put(b.getId(), Class.forName(b.getClassName()).newInstance());
70 } catch (Exception e) {
71 e.printStackTrace();
72 }
73 }
74 }
75 /**
76 * 读取xml配置文件
77 * @param path
78 */
79 private void readXML(String path) {
80 // TODO Auto-generated method stub
81 SAXReader reader=new SAXReader();//创建读取器
82 URL url=getClass().getClassLoader().getResource(path);
83 Document doc=null;
84 try {
85 doc=reader.read(url);
86 //存放命名空间
87 Map<String,String> nsps=new HashMap<String,String>();
88 nsps.put("ns", "http://www.springframework.org/schema/beans");
89 XPath ePath=doc.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
90 ePath.setNamespaceURIs(nsps);
91 List<Element> eList=ePath.selectNodes(doc);//获取文档下所有bean节点
92 for(Element e:eList){
93 String id=e.attributeValue("id");
94 String className=e.attributeValue("class");
95
96 BeanDefinition bDefinition=new BeanDefinition(id, className);
97 //读取property
98 XPath pXPath=e.createXPath("ns:property");//当前元素
99 pXPath.setNamespaceURIs(nsps);
100 List<Element> pros=pXPath.selectNodes(e);
101 for(Element e2:pros){
102 String name=e2.attributeValue("name");
103 String ref=e2.attributeValue("ref");
104 String value=e2.attributeValue("value");
105
106 //System.out.println(name+" "+ref);
107 PropertyDefinition pd=new PropertyDefinition(name, ref,value);
108 bDefinition.getProperties().add(pd);
109 }
110 beanDefinitions.add(bDefinition);
111 }
112 } catch (Exception e) {
113 // TODO Auto-generated catch block
114 e.printStackTrace();
115 }
116 }
117 public Object getBean(String id){
118 return beans.get(id);
119 }
120 }

 加入注解解析功能:

定义注解:

 1 import java.lang.annotation.ElementType;
2 import java.lang.annotation.Retention;
3 import java.lang.annotation.RetentionPolicy;
4 import java.lang.annotation.Target;
5
6 //表示使用的范围,编译器、运行期
7 @Retention(RetentionPolicy.RUNTIME)
8 //注解可以加入的位置
9 @Target({ElementType.FIELD,ElementType.METHOD})
10 public @interface ItcastResource {
11 String name() default "";
12 }

注解解析器做的事情。该方法加入到上面ItcastClassPathXMLApplicationContext中的构造函数中。

 1 private void annotationInject() {
2 // TODO Auto-generated method stub
3 for(BeanDefinition bd:beanDefinitions){
4 Object bean=getBean(bd.getId());
5 if(bean!=null){
6 try {
7 //取得所有的属性
8 PropertyDescriptor[] pdps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
9 for(PropertyDescriptor pdesc:pdps){
10 //判断setter上是否存在注解
11 Method setter=pdesc.getWriteMethod();
12 if(setter!=null&& setter.isAnnotationPresent(ItcastResource.class)){
13 //取出注解的name属性
14 ItcastResource itRes=setter.getAnnotation(ItcastResource.class);
15 Object value=null;
16 if(itRes.name()!=null&&!itRes.name().equals("")){
17 value=getBean(itRes.name());
18 }else{
19 //取得属性的名称
20 value=getBean(pdesc.getName());
21 if(value==null){//按类型找
22 //遍历所有的bean
23 for(String key:beans.keySet()){
24 //类型匹配
25 if(pdesc.getPropertyType().isAssignableFrom(beans.get(key).getClass())){
26 value=beans.get(key);
27 break;
28 }
29
30 }
31 }
32 }
33 setter.setAccessible(true);
34 setter.invoke(bean, value);
35 }
36 }
37 //取得字段
38 Field[] fields=bean.getClass().getDeclaredFields();
39 for(Field f:fields){
40 //是否存在注解
41 if(f.isAnnotationPresent(ItcastResource.class)){
42 ItcastResource itRes=f.getAnnotation(ItcastResource.class);
43 Object value=null;
44 if(itRes.name()!=null&&!itRes.name().equals("")){
45 value=getBean(itRes.name());
46 }else{
47 //取得属性的名称
48 value=getBean(f.getName());
49 if(value==null){//按类型找
50 //遍历所有的bean
51 for(String key:beans.keySet()){
52 //类型匹配
53 if(f.getType().isAssignableFrom(beans.get(key).getClass())){
54 value=beans.get(key);
55 break;
56 }
57
58 }
59 }
60 }
61 f.setAccessible(true);
62 f.set(bean, value);
63 }
64 }
65 } catch (Exception e) {
66 // TODO Auto-generated catch block
67 e.printStackTrace();
68 }
69
70 }
71 }
72 }



原文地址:https://www.cnblogs.com/tazi/p/2306575.html