`

七 编码剖析@Resource注解的实现原理

 
阅读更多
七 编码剖析@Resource注解的实现原理

ItcastResource.java

view plaincopy to clipboardprint?
01.package junit.test;   
02.  
03.import java.lang.annotation.ElementType;   
04.import java.lang.annotation.Retention;   
05.import java.lang.annotation.RetentionPolicy;   
06.import java.lang.annotation.Target;   
07.  
08.@Retention(RetentionPolicy.RUNTIME)   
09.@Target({ElementType.FIELD, ElementType.METHOD})   
10.public @interface ItcastResource {   
11.    public String name() default "";   
12.}  
package junit.test;

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 {
	public String name() default "";
}


PropertyDefinition .java

view plaincopy to clipboardprint?
01.package junit.test;   
02.  
03.public class PropertyDefinition {   
04.    private String name;   
05.    private String ref;   
06.    private String value;   
07.       
08.    public String getValue() {   
09.        return value;   
10.    }   
11.  
12.    public void setValue(String value) {   
13.        this.value = value;   
14.    }   
15.  
16.    public PropertyDefinition(String name, String ref, String value) {   
17.        this.name = name;   
18.        this.ref = ref;   
19.        this.value = value;   
20.    }   
21.       
22.    public String getName() {   
23.        return name;   
24.    }   
25.    public void setName(String name) {   
26.        this.name = name;   
27.    }   
28.    public String getRef() {   
29.        return ref;   
30.    }   
31.    public void setRef(String ref) {   
32.        this.ref = ref;   
33.    }   
34.       
35.}  
package junit.test;

public class PropertyDefinition {
	private String name;
	private String ref;
	private String value;
	
	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public PropertyDefinition(String name, String ref, String value) {
		this.name = name;
		this.ref = ref;
		this.value = value;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getRef() {
		return ref;
	}
	public void setRef(String ref) {
		this.ref = ref;
	}
	
}
 

BeanDefinition.java

view plaincopy to clipboardprint?
01.package junit.test;   
02.  
03.import java.util.ArrayList;   
04.import java.util.List;   
05.  
06.public class BeanDefinition {   
07.    private String id;   
08.    private String className;   
09.    private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>();   
10.       
11.    public BeanDefinition(String id, String className) {   
12.        this.id = id;   
13.        this.className = className;   
14.    }   
15.    public String getId() {   
16.        return id;   
17.    }   
18.    public void setId(String id) {   
19.        this.id = id;   
20.    }   
21.    public String getClassName() {   
22.        return className;   
23.    }   
24.    public void setClassName(String className) {   
25.        this.className = className;   
26.    }   
27.    public List<PropertyDefinition> getPropertys() {   
28.        return propertys;   
29.    }   
30.    public void setPropertys(List<PropertyDefinition> propertys) {   
31.        this.propertys = propertys;   
32.    }   
33.       
34.}  
package junit.test;

import java.util.ArrayList;
import java.util.List;

public class BeanDefinition {
	private String id;
	private String className;
	private List<PropertyDefinition> propertys = new ArrayList<PropertyDefinition>();
	
	public BeanDefinition(String id, String className) {
		this.id = id;
		this.className = className;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	public List<PropertyDefinition> getPropertys() {
		return propertys;
	}
	public void setPropertys(List<PropertyDefinition> propertys) {
		this.propertys = propertys;
	}
	
}
 

ItcastClassPathXMLApplicationContext.java

view plaincopy to clipboardprint?
01.package junit.test;   
02.  
03.import java.beans.Introspector;   
04.import java.beans.PropertyDescriptor;   
05.import java.lang.reflect.Field;   
06.import java.lang.reflect.Method;   
07.import java.net.URL;   
08.import java.util.ArrayList;   
09.import java.util.HashMap;   
10.import java.util.List;   
11.import java.util.Map;   
12.  
13.import org.apache.commons.beanutils.ConvertUtils;   
14.import org.dom4j.Document;   
15.import org.dom4j.Element;   
16.import org.dom4j.XPath;   
17.import org.dom4j.io.SAXReader;   
18.  
19./**  
20. * 传智传客版容器  
21. *  
22. */  
23.public class ItcastClassPathXMLApplicationContext {   
24.    private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();   
25.    private Map<String, Object> sigletons = new HashMap<String, Object>();   
26.       
27.    public ItcastClassPathXMLApplicationContext(String filename){   
28.        this.readXML(filename);   
29.        this.instanceBeans();   
30.        this.annotationInject();   
31.        this.injectObject();   
32.    }   
33.    /**  
34.     * 通过注解实现注入依赖对象  
35.     */  
36.    private void annotationInject() {   
37.        for(String beanName : sigletons.keySet()){   
38.            Object bean = sigletons.get(beanName);   
39.            if(bean!=null){   
40.                try {   
41.                    PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();   
42.                    for(PropertyDescriptor properdesc : ps){   
43.                        Method setter = properdesc.getWriteMethod();//获取属性的setter方法   
44.                        if(setter!=null && setter.isAnnotationPresent(ItcastResource.class)){   
45.                            ItcastResource resource = setter.getAnnotation(ItcastResource.class);   
46.                            Object value = null;   
47.                            if(resource.name()!=null && !"".equals(resource.name())){   
48.                                value = sigletons.get(resource.name());   
49.                            }else{   
50.                                value = sigletons.get(properdesc.getName());   
51.                                if(value==null){   
52.                                    for(String key : sigletons.keySet()){   
53.                                        if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){   
54.                                            value = sigletons.get(key);   
55.                                            break;   
56.                                        }   
57.                                    }   
58.                                }                                  
59.                            }   
60.                            setter.setAccessible(true);   
61.                            setter.invoke(bean, value);//把引用对象注入到属性   
62.                        }   
63.                    }   
64.                    Field[] fields = bean.getClass().getDeclaredFields();   
65.                    for(Field field : fields){   
66.                        if(field.isAnnotationPresent(ItcastResource.class)){   
67.                            ItcastResource resource = field.getAnnotation(ItcastResource.class);   
68.                            Object value = null;   
69.                            if(resource.name()!=null && !"".equals(resource.name())){   
70.                                value = sigletons.get(resource.name());   
71.                            }else{   
72.                                value = sigletons.get(field.getName());   
73.                                if(value==null){   
74.                                    for(String key : sigletons.keySet()){   
75.                                        if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){   
76.                                            value = sigletons.get(key);   
77.                                            break;   
78.                                        }   
79.                                    }   
80.                                }                                  
81.                            }   
82.                            field.setAccessible(true);//允许访问private字段   
83.                            field.set(bean, value);   
84.                        }   
85.                    }   
86.                } catch (Exception e) {   
87.                    e.printStackTrace();   
88.                }   
89.            }   
90.        }   
91.    }   
92.  
93.    /**  
94.     * 为bean对象的属性注入值  
95.     */  
96.    private void injectObject() {   
97.        for(BeanDefinition beanDefinition : beanDefines){   
98.            Object bean = sigletons.get(beanDefinition.getId());   
99.            if(bean!=null){   
100.                try {   
101.                    PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();   
102.                    for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){   
103.                        for(PropertyDescriptor properdesc : ps){   
104.                            if(propertyDefinition.getName().equals(properdesc.getName())){   
105.                                Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private   
106.                                if(setter!=null){   
107.                                    Object value = null;   
108.                                    if(propertyDefinition.getRef()!=null && !"".equals(propertyDefinition.getRef().trim())){   
109.                                        value = sigletons.get(propertyDefinition.getRef());   
110.                                    }else{   
111.                                        value = ConvertUtils.convert(propertyDefinition.getValue(), properdesc.getPropertyType());   
112.                                    }   
113.                                    setter.setAccessible(true);   
114.                                    setter.invoke(bean, value);//把引用对象注入到属性   
115.                                }   
116.                                break;   
117.                            }   
118.                        }   
119.                    }   
120.                } catch (Exception e) {   
121.                }   
122.            }   
123.        }   
124.    }   
125.    /**  
126.     * 完成bean的实例化  
127.     */  
128.    private void instanceBeans() {   
129.        for(BeanDefinition beanDefinition : beanDefines){   
130.            try {   
131.                if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim()))   
132.                    sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());   
133.            } catch (Exception e) {   
134.                e.printStackTrace();   
135.            }   
136.        }   
137.           
138.    }   
139.    /**  
140.     * 读取xml配置文件  
141.     * @param filename  
142.     */  
143.    private void readXML(String filename) {   
144.           SAXReader saxReader = new SAXReader();      
145.            Document document=null;      
146.            try{   
147.             URL xmlpath = this.getClass().getClassLoader().getResource(filename);   
148.             document = saxReader.read(xmlpath);   
149.             Map<String,String> nsMap = new HashMap<String,String>();   
150.             nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间   
151.             XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径   
152.             xsub.setNamespaceURIs(nsMap);//设置命名空间   
153.             List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点    
154.             for(Element element: beans){   
155.                String id = element.attributeValue("id");//获取id属性值   
156.                String clazz = element.attributeValue("class"); //获取class属性值           
157.                BeanDefinition beanDefine = new BeanDefinition(id, clazz);   
158.                XPath propertysub =  element.createXPath("ns:property");   
159.                propertysub.setNamespaceURIs(nsMap);//设置命名空间   
160.                List<Element> propertys = propertysub.selectNodes(element);   
161.                for(Element property : propertys){                     
162.                    String propertyName = property.attributeValue("name");   
163.                    String propertyref = property.attributeValue("ref");   
164.                    String propertyValue = property.attributeValue("value");   
165.                    PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref, propertyValue);   
166.                    beanDefine.getPropertys().add(propertyDefinition);   
167.                }   
168.                beanDefines.add(beanDefine);   
169.             }    
170.            }catch(Exception e){      
171.                e.printStackTrace();   
172.            }   
173.    }   
174.    /**  
175.     * 获取bean实例  
176.     * @param beanName  
177.     * @return  
178.     */  
179.    public Object getBean(String beanName){   
180.        return this.sigletons.get(beanName);   
181.    }   
182.}  
package junit.test;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
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 {
	private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
	private Map<String, Object> sigletons = new HashMap<String, Object>();
	
	public ItcastClassPathXMLApplicationContext(String filename){
		this.readXML(filename);
		this.instanceBeans();
		this.annotationInject();
		this.injectObject();
	}
	/**
	 * 通过注解实现注入依赖对象
	 */
	private void annotationInject() {
		for(String beanName : sigletons.keySet()){
			Object bean = sigletons.get(beanName);
			if(bean!=null){
				try {
					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDescriptor properdesc : ps){
						Method setter = properdesc.getWriteMethod();//获取属性的setter方法
						if(setter!=null && setter.isAnnotationPresent(ItcastResource.class)){
							ItcastResource resource = setter.getAnnotation(ItcastResource.class);
							Object value = null;
							if(resource.name()!=null && !"".equals(resource.name())){
								value = sigletons.get(resource.name());
							}else{
								value = sigletons.get(properdesc.getName());
								if(value==null){
									for(String key : sigletons.keySet()){
										if(properdesc.getPropertyType().isAssignableFrom(sigletons.get(key).getClass())){
											value = sigletons.get(key);
											break;
										}
									}
								}								
							}
							setter.setAccessible(true);
							setter.invoke(bean, value);//把引用对象注入到属性
						}
					}
					Field[] fields = bean.getClass().getDeclaredFields();
					for(Field field : fields){
						if(field.isAnnotationPresent(ItcastResource.class)){
							ItcastResource resource = field.getAnnotation(ItcastResource.class);
							Object value = null;
							if(resource.name()!=null && !"".equals(resource.name())){
								value = sigletons.get(resource.name());
							}else{
								value = sigletons.get(field.getName());
								if(value==null){
									for(String key : sigletons.keySet()){
										if(field.getType().isAssignableFrom(sigletons.get(key).getClass())){
											value = sigletons.get(key);
											break;
										}
									}
								}								
							}
							field.setAccessible(true);//允许访问private字段
							field.set(bean, value);
						}
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 为bean对象的属性注入值
	 */
	private void injectObject() {
		for(BeanDefinition beanDefinition : beanDefines){
			Object bean = sigletons.get(beanDefinition.getId());
			if(bean!=null){
				try {
					PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){
						for(PropertyDescriptor properdesc : ps){
							if(propertyDefinition.getName().equals(properdesc.getName())){
								Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private
								if(setter!=null){
									Object value = null;
									if(propertyDefinition.getRef()!=null && !"".equals(propertyDefinition.getRef().trim())){
										value = sigletons.get(propertyDefinition.getRef());
									}else{
										value = ConvertUtils.convert(propertyDefinition.getValue(), properdesc.getPropertyType());
									}
									setter.setAccessible(true);
									setter.invoke(bean, value);//把引用对象注入到属性
								}
								break;
							}
						}
					}
				} catch (Exception e) {
				}
			}
		}
	}
	/**
	 * 完成bean的实例化
	 */
	private void instanceBeans() {
		for(BeanDefinition beanDefinition : beanDefines){
			try {
				if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim()))
					sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}
	/**
	 * 读取xml配置文件
	 * @param filename
	 */
	private void readXML(String filename) {
	       SAXReader saxReader = new SAXReader();   
	        Document document=null;   
	        try{
	         URL xmlpath = this.getClass().getClassLoader().getResource(filename);
	         document = saxReader.read(xmlpath);
	         Map<String,String> nsMap = new HashMap<String,String>();
	         nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间
	         XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
	         xsub.setNamespaceURIs(nsMap);//设置命名空间
	         List<Element> beans = xsub.selectNodes(document);//获取文档下所有bean节点 
	         for(Element element: beans){
	            String id = element.attributeValue("id");//获取id属性值
	            String clazz = element.attributeValue("class"); //获取class属性值        
	            BeanDefinition beanDefine = new BeanDefinition(id, clazz);
	            XPath propertysub =  element.createXPath("ns:property");
	            propertysub.setNamespaceURIs(nsMap);//设置命名空间
	            List<Element> propertys = propertysub.selectNodes(element);
	            for(Element property : propertys){	            	
	            	String propertyName = property.attributeValue("name");
	            	String propertyref = property.attributeValue("ref");
	            	String propertyValue = property.attributeValue("value");
	            	PropertyDefinition propertyDefinition = new PropertyDefinition(propertyName, propertyref, propertyValue);
	            	beanDefine.getPropertys().add(propertyDefinition);
	            }
	            beanDefines.add(beanDefine);
	         } 
	        }catch(Exception e){   
	            e.printStackTrace();
	        }
	}
	/**
	 * 获取bean实例
	 * @param beanName
	 * @return
	 */
	public Object getBean(String beanName){
		return this.sigletons.get(beanName);
	}
}
 

实际上也就是通过了反射技术来构造对象并且赋值,只是用到了注解的方法,并且利用@interface来构造自定义的注解类型。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics