spring IOC(DI)实验

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring IOC(DI)实验相关的知识,希望对你有一定的参考价值。

软件151  张鑫栋

一、IOC的意思是控件反转也就是由容器控制程序之间的关系,把控件权交给了外部容器,之前的写法,由程序代码直接操控,而现在控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。DI(Dependency Injection,依赖注入)。IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。

IOC实现的原理:

技术分享

 

定义DAO接口和接口的实现类

 

package com.dao; 

public interface PersonDAO {  

public void save();  

}  

package com.dao.impl;   

import com.dao.PersonDAO;  

public class PersonDaoImpl implements PersonDAO {  

    @Override  

    public void save() {  

    System.out.println("保存");  

    } 

创建一个Junit测试类

 

package com.test;  

import org.junit.Test;  

import org.springframework.context.ApplicationContext;  

import org.springframework.context.support.ClassPathXmlApplicationContext;  

import com.dao.PersonDAO;  

import com.myUtil.MyClassPathXmlApplicationContext;  

import com.service.PersonService; 

public class PersonTest {  

    @Test  

    public void instanceSpring1(){  

      /*

         * spring 的实现 

         */  

        //IOC  

        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");  

        PersonDAO pd = (PersonDAO) ac.getBean("personDAO");  

        pd.save();  

        //DI  

        PersonService ps = (PersonService) ac.getBean("personService");  

        ps.save();  

    }  

    @Test  

    public void instanceSpring2(){  

        /** 

         * 我的实现 

                */  

        MyClassPathXmlApplicationContext mac = new MyClassPathXmlApplicationContext("beans.xml");  

        PersonDAO mpd = (PersonDAO) mac.getBean("personDAO");  

        mpd.save();  

        //DI  

        PersonService ps = (PersonService) mac.getBean("personService");  

        ps.save();  

    }     

}  

 

方法instanceSpring1为Spring中的实现用ClassPathXmlApplicationContext类,要实现IOC的原理要定义自己的MyClassPathXmlApplicationContext首先读出beans.xml中的配置信息,通过反射机制实现bean,最后注入所需要的bean。

 

package com.myUtil; 

import java.beans.Introspector; 

import java.beans.PropertyDescriptor; 

import java.lang.reflect.Method; 

import java.net.URL; 

import java.util.ArrayList; 

import java.util.HashMap; 

import java.util.List; 

import java.util.Map; 

import org.dom4j.Document; 

import org.dom4j.Element; 

import org.dom4j.io.SAXReader; 

public class MyClassPathXmlApplicationContext { 

    // xml所有的属性 

    private ArrayList<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>(); 

    // xml中所有的bean 

    private Map<String, Object> sigletons = new HashMap<String, Object>(); 

    public MyClassPathXmlApplicationContext(String file) { 

        readXml(file); 

        instanceBeans(); 

        instanceObject(); 

    } 

    /**

     * 注入

     */ 

    private void instanceObject() { 

        for (BeanDefinition beanDefinition : beanDefinitions) { 

            //判断有没有注入属性 

            if (beanDefinition.getProperty() != null) { 

                Object bean = sigletons.get(beanDefinition.getId()); 

                if (bean != null) { 

                    try { 

                        //得到被注入bean的所有的属性 

                        PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors(); 

                        //得到所有的注入bean属性 

    for(PropertyDefinition propertyDefinition:beanDefinition.getProperty()){ 

                 for(PropertyDescriptor propertyDescriptor:ps){ 

            if(propertyDescriptor.getName().equals(propertyDefinition.getName())){ 

           Method setter = propertyDescriptor.getWriteMethod();//获取set方法 

                                    if(setter!=null){ 

                             setter.setAccessible(true);//得到private权限 

                                        //注入属性 

                                setter.invoke(bean, sigletons.get(propertyDefinition.getRef())); 

                                    }  

                                    break; 

                                } 

                            } 

                        } 

                    } catch (Exception e) { 

                        // TODO Auto-generated catch block 

                        e.printStackTrace(); 

                    } 

                }   } 

        }   }   

    /**

     * 实例所有的bean

     */ 

    private void instanceBeans() { 

        for (int i = 0; i < beanDefinitions.size(); i++) { 

            BeanDefinition bd = beanDefinitions.get(i); 

            try { 

                try { 

                    if (bd.getClassName() != null 

                            && !bd.getClassName().equals("")) 

                        sigletons.put(bd.getId(), Class.forName( 

                                bd.getClassName()).newInstance()); 

                } catch (InstantiationException e) { 

                    // TODO Auto-generated catch block 

                    e.printStackTrace(); 

                } catch (IllegalAccessException e) { 

                    // TODO Auto-generated catch block 

                    e.printStackTrace(); 

                } 

            } catch (ClassNotFoundException e) { 

                // TODO Auto-generated catch block 

                e.printStackTrace(); 

            } 

        }    } 

    /**

     * 读xml

         * @param file

     */ 

    private void readXml(String file) { 

        try { 

            SAXReader reader = new SAXReader(); // 使用SAX方式解析XML 

            URL xmlPath = this.getClass().getClassLoader().getResource(file); 

            Document doc = reader.read(xmlPath); 

            Element root = doc.getRootElement(); // 取得根节点 

            List<Element> beans = root.elements(); 

            for (Element element : beans) { 

                String id = element.attributeValue("id");// id; 

                String clazz = element.attributeValue("class"); 

                BeanDefinition bd = new BeanDefinition(id, clazz); 

                // 读取子元素 

                if (element.hasContent()) { 

                    List<Element> propertys = element.elements(); 

                    for (Element property : propertys) { 

                        String name = property.attributeValue("name"); 

                        String ref = property.attributeValue("ref"); 

                        PropertyDefinition pd = new PropertyDefinition(name, 

                                ref); 

                        bd.getProperty().add(pd); 

                    }     } 

                beanDefinitions.add(bd); 

            } 

        } catch (Exception e) { 

            // TODO: handle exception 

        } 

    } 

    /**

     * 通过名字得到bean

     * @param str

     * @return

     */ 

    public Object getBean(String str) { 

        return sigletons.get(str); 

    } }

 

读取所的bean实体

 

package com.myUtil;  

import java.util.ArrayList; 

import java.util.List; 

public class BeanDefinition { 

    private String id; 

    private String className; 

    private List<PropertyDefinition> property = new ArrayList<PropertyDefinition>(); 

    public BeanDefinition(String id, String className) { 

        super(); 

        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> getProperty() { 

        return property; 

    } 

    public void setProperty(List<PropertyDefinition> property) { 

        this.property = property; 

    } 

 

注入属性实体

 

[java] view plain copy

package com.myUtil; 

 

public class PropertyDefinition { 

    private String name; 

    private String ref; 

    public PropertyDefinition(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; 

    } 

 

业务接口和实现类

 

package com.service;

public interface PersonService { 

    public void save(); 

[java] view plain copy

package com.service.impl;   

import com.dao.PersonDAO; 

import com.service.PersonService;    

public class PersonServiceImpl implements PersonService{ 

    private PersonDAO pdo; 

 

    public PersonDAO getPdo() { 

        return pdo; 

    } 

    public void setPdo(PersonDAO pdo) { 

        this.pdo = pdo; 

    } 

    @Override 

    public void save() { 

        pdo.save(); 

    } 

beans.xml配置

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    

    xsi:schemaLocation="http://www.springframework.org/schema/beans 

           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">   

    <bean id="personDAO" class="com.dao.impl.PersonDaoImpl"></bean> 

    <bean id="personService" class="com.service.impl.PersonServiceImpl"> 

        <property name="pdo" ref="personDAO"></property> 

    </bean> 

</beans> 

 

以上是关于spring IOC(DI)实验的主要内容,如果未能解决你的问题,请参考以下文章

spring ioc Di

Spring -- IOC/DI 基础概念的理解

Spring中IOC与DI的的区别

JAVA-Spring框架之IOC(DI)

spring 依赖注入(DI)与控制反转(IOC)

Spring基础-IOC与DI(控制反转与依赖注入)