`
zhouxingfu520
  • 浏览: 422893 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

spring深入源码2 简单实现ioc机制 注解形式

阅读更多

上一篇文章 我用了xml形式 实现自己简单版的spring ioc依赖注入  这节主要利用注解形式实现 和上集内容一样 只是加了读取注解的方法。

 

DAO接口

 

    public interface PersonDao {  
      
        public void add();  
      
    }  

 

 

实现类

 

    package cn.leam.dao.impl;  
      
    import cn.leam.dao.PersonDao;  
      
    public class PersonDaoBean implements PersonDao {  
        public void add(){  
            System.out.println("执行add()方法");  
        }  
    }  

 

 

服务接口

    public interface PersonService {  
      
        public void save();  
      
    }  
 

服务实现类

    public class PersonServiceBean implements PersonService {  
        @LeamResource private PersonDao personDao;  
          
        public PersonDao getPersonDao() {  
            return personDao;  
        }  
      
        public void setPersonDao(PersonDao personDao) {  
            this.personDao = personDao;  
        }  
          
        public void save(){  
            personDao.add();  
        }  
    }  

 

<?xml version="1.0" encoding="UTF-8"?>  
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"       
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context 
<!--需要加上注解-->
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
        
<!--需要加上注解标签-->
<context:annotation-config/>
               <bean id="personDao" class="cn.leam.dao.impl.PersonDaoBean"></bean>  
              <bean id="personService" class="cn.leam.service.impl.PersonServiceBean">  
               <!--这里把xml定义的属性去掉 我们使用注解获取 
                  <property name="personDao" ref="personDao"></property>  -->
              </bean>  
    </beans>  

 

下面模拟spring对xml配置的类进行实例化

 

存放属性的对象

 

    public class prosDefinition {  
        private String name;  
        private String ref;  
          
        public ProsDefinition(String name, String ref) {  
            this.name = name;  
            this.ref = ref;  
        }  
          
        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;  
        }  
          
    }  

 

存放bean的 对象

 

    public class Definition {  
        private String id;  
        private String className;  
        private List<ProsDefinition> propertys = new ArrayList<ProsDefinition>();  
          
        public Definition(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;  
        }  
          
    }  

 

加上注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface LeamResource {
	public String name() default "";
}
 

 

这里是关键点  所有代码都在这里    使用dom4j 解析xml文件中的bean  并获取id和class  再判断元素中是否有引用元素对其一并获取出来存放才Map中 利用java反射一个一个进行实例化

 

    /** 
     * 学习版容器 
     * 
     */  
    public class LeamClassPathXMLApplicationContext {  
        private List<Definition> beanDefines = new ArrayList<Definition>();  
        private Map<String, Object> sigletons = new HashMap<String, Object>();  
          
        public LeamClassPathXMLApplicationContext(String filename){  
            this.readXML(filename);  
            this.instanceBeans();  
            this.annotationInject();
            this.injectObject();  
        }  
        /** 
         * 为bean对象的属性注入值 
         */  
        private void injectObject() {  
            for(Definition beanDefinition : beanDefines){  
                Object bean = sigletons.get(beanDefinition.getId());  
                if(bean!=null){  
                    try {  
                        PropertyDescriptor[] ps = 
                    Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  
                 for(ProsDefinition propertyDefinition : beanDefinition.getPropertys()){  
                            for(PropertyDescriptor properdesc : ps){  
                              if(propertyDefinition.getName().equals(properdesc.getName())){  
                   Method setter = properdesc.getWriteMethod();//获取属性的setter方法
                                    if(setter!=null){  
                      Object value = sigletons.get(propertyDefinition.getRef());  
                                        setter.setAccessible(true);  
                                        setter.invoke(bean, value);//把引用对象注入到属性  
                                    }  
                                    break;  
                                }  
                            }  
                        }  
                    } catch (Exception e) {  
                    }  
                }  
            }  
        }  
        /** 
         * 完成bean的实例化 
         */  
        private void instanceBeans() {  
            for(Definition 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属性值          
                    Definition beanDefine = new Definition(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");  
    ProsDefinition propertyDefinition = new ProsDefinition(propertyName, propertyref);  
                        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);  
        }  
    }  



/**
	 * 通过注解实现注入依赖对象
	 */
	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方法
                                        //如果是用了注解 将在set方法注入进去
					if(setter!=null && setter.isAnnotationPresent(LeamResource.class)){
					LeamResource resource = setter.getAnnotation(LeamResource.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(LeamResource.class)){
					LeamResource resource = field.getAnnotation(LeamResource.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();
				}
			}
		}
	}

 

 

 

    public class SpringTest {  
      
        @BeforeClass  
        public static void setUpBeforeClass() throws Exception {  
        }  
      
        @Test public void instanceSpring(){  
            LeamClassPathXMLApplicationContext ctx = new  
                                          LeamClassPathXMLApplicationContext("beans.xml");  
            PersonService personService = (PersonService)ctx.getBean("personService");  
            personService.save();         
        }  
    }  

 

 

最终输出

 

"执行add()方法" 说明实例化成功  否则 出现空指针异常

分享到:
评论

相关推荐

    Spring源码分析_Spring_IOC

    ### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...

    Spring IoC源码深度剖析开源架构源码2021.pdf

    标题《Spring IoC源码深度剖析开源架构源码2021.pdf》和描述《Spring IoC源码深度剖析开源架构源码2021.pdf》表明该文档主要面向于分析Spring框架中控制反转(IoC)容器的核心源码,解析和理解其内部的工作机制及...

    spring 源码中文注释

    在源码分析的过程中,读者会深入理解Spring的内部工作机制,例如如何解析配置、如何创建bean实例、如何实现AOP代理等。这将有助于开发者编写更高效、更健壮的代码,也能为参与Spring的扩展或定制打下坚实基础。 总...

    Spring ioc源码解读

    通过对Spring IoC容器的理解和源码分析,我们可以深入了解到Spring框架是如何管理和控制应用对象的生命周期及依赖关系的。在实际开发中,了解Spring IoC容器的工作原理有助于更好地利用Spring框架,提高开发效率和...

    spring源码中英文注释

    这个压缩包文件中的"spring源码 中英文注释"为开发者提供了一个深入理解Spring框架内部工作原理的机会。通过阅读源码和注释,我们可以更清晰地了解Spring如何管理依赖注入、AOP(面向切面编程)、事务管理、上下文...

    Spring4 IOC 示例源码

    在这个示例源码中,我们可以深入理解并学习如何在实际项目中运用Spring的IOC容器来管理对象的生命周期和依赖关系。 1. **Spring 框架介绍** Spring是一个开源的Java平台,它提供了全面的企业级应用开发解决方案,...

    深入解析Spring IoC源码:核心机制与实践应用

    通过对Spring IoC源码的深入解析,我们可以了解到Spring如何高效地管理Bean的生命周期,以及如何通过注解实现灵活的配置。这对于开发者来说,不仅有助于提升代码质量,还能更好地利用Spring框架提供的功能,提高开发...

    spring源码(注释+测试版)

    这份"spring源码(注释+测试版)"提供了Spring框架的源代码,带有注释和测试用例,对于开发者深入理解Spring的工作原理非常有帮助。 1. **spring-core**:这是Spring框架的基础模块,包含了核心的工具类和资源处理...

    Spring AOP IOC源码笔记.pdf

    本笔记将深入探讨这两个概念以及它们在Spring中的实现。 1. Spring框架简介: Spring作为一个轻量级的开源框架,旨在简化企业级应用的开发。它通过提供IOC容器,实现了对象的创建、管理和依赖注入,减轻了开发者对...

    spring ioc

    标题 "Spring IOC" 描述了我们讨论的核心主题——Spring 框架中的依赖注入(Inversion of Control,简称 IOC)机制。Spring 是一个广泛应用的 Java 应用开发框架,其核心特性之一就是IOC,它极大地简化了软件组件...

    基于Maven构建的Spring IoC源码实例

    在"基于Maven构建的Spring IoC源码实例"中,我们可以学到如何使用Maven搭建Spring项目,并通过Spring IoC实现组件间的依赖注入。以下是这个实例中可能包含的关键知识点: 1. **Maven项目结构**:了解标准的Maven...

    模拟Spring的IOC

    理解并模拟Spring的IOC机制对于深入学习Spring以及提升软件设计能力具有重要意义。 **1. 控制反转(IOC)概念** 控制反转是一种设计思想,它将对象的创建和管理权交给容器,而不是由对象自身负责。这样可以降低对象...

    简单记录spring 实现IOC的流程

    在这个简单的记录中,我们将深入理解Spring如何实现IOC的流程,以及这一过程对软件开发的影响。 首先,我们需要明确什么是IOC和DI。在传统的编程模式中,开发者需要在代码中手动创建对象并管理它们的生命周期。而...

    Spring源码解析4章150页+Spring3.2.4中文注释源码

    4、Spring源码下载 二阶段 1、什么是IOC/DI 2、SpringIOC体系结构 3、源码分析-IOC容器的初始化 4、源码分析-IOC容器的依赖注入 5、源码分析-IOC容器的高级特性 三阶段 Spring AOP的涉及原理及具体实践 SpringJDBC...

    spring 编译后源码(有注释)

    你可以深入到源码层面,了解 Spring 如何实现这些功能,这对于提升你的 Java 和 Spring 技能大有裨益。通过阅读源码,你将能够掌握 IoC 容器的创建过程、AOP 切面的编织方式、以及 MVC 框架的请求处理流程等关键概念...

    spring1.2.6源码

    Spring框架是Java开发中不可或缺的一部分,它以其IoC(Inversion of Control)和AOP(Aspect-Oriented Programming)的核心特性赢得了广泛的认可。版本1.2.6是Spring早期的一个稳定版本,对于初学者和想要深入理解...

    自己动手实现IOC和MVC源码

    【标题】"自己动手实现IOC和MVC源码"揭示了本文的核心内容,即通过实践来理解并构建IoC(Inversion of Control)和MVC(Model-View-Controller)这两种重要的软件设计模式的源代码。这两者是现代Java Web开发中...

    深入解析Spring IoC:源码与实践指南

    在深入解析Spring IoC的过程中,我们首先关注的是其核心组件——IoC(Inversion of Control,控制反转)机制。Spring框架通过IoC容器管理应用程序的组件,实现了依赖注入,使得对象之间的依赖关系由容器负责建立和...

    spring5.0.1源码包

    通过研究Spring 5.0.1的源码,开发者不仅可以深入理解框架的工作机制,还能学习到优秀的软件设计原则和模式,提升自己的编程技能。同时,源码也是寻找问题解决方案、定制功能和贡献社区的宝贵资源。

    spring IOC学习源码

    `.idea`文件夹是IntelliJ IDEA的工作空间配置,与Spring源码学习关联不大,通常在提交代码时会被忽略。 为了深入理解Spring IOC,我们需要关注以下几个源码的关键部分: 1. **BeanDefinitionReader**:读取XML配置...

Global site tag (gtag.js) - Google Analytics