spring注解原理

package autowired;

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.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

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();
    }
}

猜你喜欢

转载自www.cnblogs.com/wujf/p/9173389.html