zoukankan      html  css  js  c++  java
  • 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();
        }
    }

    有追求,才有动力!

    向每一个软件工程师致敬!

    by wujf

    mail:921252375@qq.com

  • 相关阅读:
    未进入Kali Linux系统修改修改密码的方法
    SQL 修改字段名,数据类型,增加字段
    在 SAE 上部署 ThinkPHP 5.0 RC4
    在 C# 里使用 F# 的 option 变量
    Retinex图像增强和暗通道去雾的关系及其在hdr色调恢复上的应用
    暗通道去雾算法的python实现
    解析hdr图像文件的python实现
    博客说明
    retinex图像增强算法的研究
    我知道的JavaScript设计模式(桥接)应用之验证器
  • 原文地址:https://www.cnblogs.com/wujf/p/9173389.html
Copyright © 2011-2022 走看看