spring 学习笔记 -- 依赖注入基本原理框架

spring的核心类ApplicationContext提供getBean方法来让我们从容器中提取出容器替我们实例化的类

这个过程的原理,下面用简单的代码对框架流程进行解释

当我们启动Spring容器的时候他会运行以下几个过程:

载入Xml配置文件(readXML(String filename))在Spring这个由ApplicationContext类完毕

第一步主要是把解析文件中的bean加载到BeanDefinition类中

/*
 * 读取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 nsMap = new HashMap();
        nsMap.put("ns","http://www.springframework.org/schema/beans");//加入命名空间
        XPath xsub = 
            document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径
        xsub.setNamespaceURIs(nsMap);//设置命名空间
        List 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 propertys = propertysub.selectNodes(element);
            for(Element property : propertys){                  
                String propertyName = property.attributeValue("name");
                String propertyref = property.attributeValue("ref");
                PropertyDefinition propertyDefinition 
                    = new PropertyDefinition(propertyName, propertyref);
                    beanDefine.getPropertys().add(propertyDefinition);
            }
            beanDefines.add(beanDefine);
        } 
     }catch(Exception e){   
         e.printStackTrace();
     }
}

2、Bean的实例化 
在配置文件以bean的id为key。BeanDefinition为value放到Map中

/*
 * 完毕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();
            }
    }

}

3、为Bean的输入注入值。完毕依赖注入

/*
 * 为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 = 
                                     sigletons.get(propertyDefinition.getRef());
                                    setter.setAccessible(true);
                                    setter.invoke(bean, value);//把引用对象注入到属性
                                }
                                break;
                            }
                        }
                    }
                } catch (Exception e) {
            }
        }
    }
}

以上Spring依赖注入的过程,再就是各种细节了。比方懒载入、单例等的额外处理了,后续继续学习

你可能感兴趣的:(spring)