1. 程式人生 > >spring中註解的實現原理,幫助理解@autowired @resource區別

spring中註解的實現原理,幫助理解@autowired @resource區別



package com.yt.annotation;  
  
import java.beans.Introspector;  
import java.beans.PropertyDescriptor;  
import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.Iterator;  
import java.util.List;  
import java.util.Map;  
import org.apache.log4j.Logger;  
import org.dom4j.Document;  
import org.dom4j.DocumentException;  
import org.dom4j.Element;  
import org.dom4j.io.SAXReader;  
  
/** 
 * @Description: spring中的註解原理 
 * @ClassName: ClassPathXMLApplicationContext 
 * @Project: spring-aop 
 * @Author: zxf 
 * @Date: 2011-6-3 
 */  
public class ClassPathXMLApplicationContext {  
  
    Logger log = Logger.getLogger(ClassPathXMLApplicationContext.class);  
  
    List<BeanDefine> beanList = new ArrayList<BeanDefine>();  
    Map<String, Object> sigletions = new HashMap<String, Object>();  
  
    public ClassPathXMLApplicationContext(String fileName) {  
        //讀取配置檔案中管理的bean  
        this.readXML(fileName);  
        //例項化bean  
        this.instancesBean();  
        //註解處理器  
        this.annotationInject();  
    }  
  
    /** 
     * 讀取Bean配置檔案 
     * @param fileName 
     * @return 
     */  
    @SuppressWarnings("unchecked")  
    public void readXML(String fileName) {  
        Document document = null;  
        SAXReader saxReader = new SAXReader();  
        try {  
            ClassLoader classLoader =   
                Thread.currentThread().getContextClassLoader();  
            document = saxReader.read(classLoader.getResourceAsStream(fileName));  
            Element beans = document.getRootElement();  
            for (Iterator<Element> beansList = beans.elementIterator();   
                beansList.hasNext();) {  
                Element element = beansList.next();  
                BeanDefine bean = new BeanDefine(  
                        element.attributeValue("id"),  
                        element.attributeValue("class"));  
                beanList.add(bean);  
            }  
        } catch (DocumentException e) {  
            log.info("讀取配置檔案出錯....");  
        }  
    }  
      
    /** 
     * 例項化Bean 
     */  
    public void instancesBean() {  
        for (BeanDefine bean : beanList) {  
            try {  
                sigletions.put(bean.getId(),   
                        Class.forName(bean.getClassName()).newInstance());  
            } catch (Exception e) {  
                log.info("例項化Bean出錯...");  
            }  
        }  
    }  
      
    /** 
     * 註解處理器 
     * 如果註解ZxfResource配置了name屬性,則根據name所指定的名稱獲取要注入的例項引用, 
     * 如果註解ZxfResource;沒有配置name屬性,則根據屬性所屬型別來掃描配置檔案獲取要 
     * 注入的例項引用 
     *  
     */  
    public void annotationInject(){  
        for(String beanName:sigletions.keySet()){  
            Object bean = sigletions.get(beanName);  
            if(bean!=null){  
                this.propertyAnnotation(bean);  
                this.fieldAnnotation(bean);  
            }  
        }  
    }  
      
    /** 
     * 處理在set方法加入的註解 
     * @param bean 處理的bean 
     */  
    public void propertyAnnotation(Object bean){  
        try {  
            //獲取其屬性的描述  
            PropertyDescriptor[] ps =   
                Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  
            for(PropertyDescriptor proderdesc : ps){  
                //獲取所有set方法  
                Method setter = proderdesc.getWriteMethod();  
                //判斷set方法是否定義了註解  
                if(setter!=null && setter.isAnnotationPresent(ZxfResource.class)){  
                    //獲取當前註解,並判斷name屬性是否為空  
                    ZxfResource resource = setter.getAnnotation(ZxfResource.class);  
                    String name ="";  
                    Object value = null;  
                    if(resource.name()!=null&&!"".equals(resource.name())){  
                        //獲取註解的name屬性的內容  
                        name = resource.name();  
                        value = sigletions.get(name);  
                    }else{ //如果當前註解沒有指定name屬性,則根據型別進行匹配  
                        for(String key : sigletions.keySet()){  
                            //判斷當前屬性所屬的型別是否在配置檔案中存在  
                            if(proderdesc.getPropertyType().isAssignableFrom(sigletions.get(key).getClass())){  
                                //獲取型別匹配的例項物件  
                                value = sigletions.get(key);  
                                break;  
                            }  
                        }  
                    }  
                    //允許訪問private方法  
                    setter.setAccessible(true);  
                    //把引用物件注入屬性  
                    setter.invoke(bean, value);   
                }  
            }  
        } catch (Exception e) {  
            log.info("set方法註解解析異常..........");  
        }  
    }  
      
    /** 
     * 處理在欄位上的註解 
     * @param bean 處理的bean 
     */  
    public void fieldAnnotation(Object bean){  
        try {  
            //獲取其全部的欄位描述  
            Field[] fields = bean.getClass().getFields();  
            for(Field f : fields){  
                if(f!=null && f.isAnnotationPresent(ZxfResource.class)){  
                    ZxfResource resource = f.getAnnotation(ZxfResource.class);  
                    String name ="";  
                    Object value = null;  
                    if(resource.name()!=null&&!"".equals(resource.name())){  
                        name = resource.name();  
                        value = sigletions.get(name);  
                    }else{  
                        for(String key : sigletions.keySet()){  
                            //判斷當前屬性所屬的型別是否在配置檔案中存在  
                            if(f.getType().isAssignableFrom(sigletions.get(key).getClass())){  
                                //獲取型別匹配的例項物件  
                                value = sigletions.get(key);  
                                break;  
                            }  
                        }  
                    }  
                    //允許訪問private欄位  
                    f.setAccessible(true);  
                    //把引用物件注入屬性  
                    f.set(bean, value);  
                }  
            }  
        } catch (Exception e) {  
            log.info("欄位註解解析異常..........");  
        }  
    }  
      
    /** 
     * 獲取Map中的對應的bean例項 
     * @param beanId 
     * @return 
     */  
    public Object getBean(String beanId) {  
        return sigletions.get(beanId);  
    }  
  
  
    public static void main(String[] args) {  
        ClassPathXMLApplicationContext path = new ClassPathXMLApplicationContext(  
                "configAnnotation.xml");  
        UserServiceImpl userService =(UserServiceImpl)path.getBean("userService");  
        userService.show();  
    }  
}