spring的ioc技术

一、了解Spring IOC/DI

  1:Spring有两大核心技术,控制反转(Inversion of Control, IOC)/依赖注入(Dependency Injection,DI)和面向切面编程(Aspect Oriented Programming,AOP)

  2. IOC/DI: 它用来管理所有的java类,类对象的创建和依赖关系都由IOC/DI进行控制。控制反转(IOC)和依赖注入(DI)在spring中表示同一种意思,只是看问题的角度不同,例如

  当在A类中new一个B类时,控制权由A掌握,可以理解为控制正转,当A类使用的B类实例有spring创建时,控制权由spring掌握,就是控制反转;

  依赖注入可以理解为A类依赖于spring,由spring注入B类。控制反转是抽象的概念,只是提出了一种“控制”的方式,而依赖注入是spring框架实现“控制反转”的具体方法。

  3. IOC/DI工作原理:spring IOC/DI的更为直观的叫法是容器,这是因为spring可以管理很多类,当需要某一类对象的实例时,spring就会提供相应的实例,就像是一个容器里面

  可以放入很多东西,需要什么就取什么。那么在spring容器中都有什么类可以使用呢?这需要预先定义在spring的配置文件中,默认的配置文件名称是applicationContext.xml

  例如在配置文件中定义了A类和B类,而A类中使用到了B类,那么配置文件中再定义好这种依赖关系,即可由Spring自动地把B类实例注入到A类中,但是,这种注入是有条件的,

  类需要符合Javabean的定义规范,在A类中需要定义对B类赋值的setter方法。这是Spring对管理的类唯一的要求,不需要像EJB那样实现框架本身的任何接口,也是spring被称

  为轻量级框架的原因。

二、IOC/DI使用到的技术

  1. JDOM:JDOM是对xml文件进行解析的技术,Spring的配置文件applicationContext.xml就是由JDOM进行解析的,它可以提取出xml文件中定义的标签和属性值。

  1.1 环境的搭建:

  

  1.2 StudentAction.java

public class StudentAction {
    private StudentService studentService;

    public void setStudentService(StudentService studentService) {
        this.studentService = studentService;
    }
    public void printName() {
        System.out.println(studentService.getName());
    }
}

  1.3 StudentServiceImpl.java

public class StudentServiceImpl implements StudentService{
    private StudentDao studentDao;

    public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
    }

    public String getName() {
        return studentDao.getName();
    }
}

  1.4 StudentService.java

public interface StudentService {
    public String getName();
}

  1.5 StudentDao.java

public interface StudentDao {
    public String getName();
}

  1.6 StudentDaoImpl.java

public class StudentDaoImpl implements StudentDao{

    public String getName() {
        return "Jike Wang";
    }
}

  1.7 测试

public class TestAction {
public static void main(String[] args) {
    //使用ApplicationContext接口的实现类ClassPathXmlApplicationContext加载spring配置文件
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
    //通过ApplicationContext接口的getBean方法获取id或name为studentAction的Bean实例
    StudentAction studentAction = (StudentAction) applicationContext.getBean("studentAction");
    //调用方法
    studentAction.printName();
}
}

  1.8 使用jdom模拟spring解析xml文件,读取关键信息

  自定义XML代码:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <!-- 定义StudentDaoImpl对象并指定id为studentDao -->
    <bean id="studentDao" class="com.IOC.dao.impl.StudentDaoImpl"></bean>
    <!-- 定义StudentServiceImpl对象并指定id为studentService-->
    <bean id="studentService" class="com.IOC.service.impl.StudentServiceImpl">
        <property name="studentDao" ref="studentDao"></property>
    </bean>
    <!-- 定义StudentAction对象并指定id为studentAction -->
    <bean id="studentAction" class="com.IOC.action.StudentAction">
        <property name="studentService" ref="studentService"></property>
    </bean>
</beans>

public class TestJDOM {
public static void main(String[] args) {
    String path = "src/main/resources/applicationContext.xml";//xml文件目录
    //用于创建文档对象
    SAXBuilder sb = new SAXBuilder();
    //构造的XML文档对象
    Document doc;
    try {
        //创建文档对象
        doc = sb.build(path);
        //得到文档的根元素<beans>
        Element rootElement = doc.getRootElement();

        //得到文档的所有<bean>
        List<Element> list = rootElement.getChildren("bean");
        for (Element element : list) {
            //得到<bean>的id属性值
            String id = element.getAttributeValue("id");
            //得到<bean>的class属性值
            String classValue = element.getAttributeValue("class");
            //得到<bean>的子元素<property>
            Element propertyElement = element.getChild("property");
            String propertyName = null;
            String propertyRef = null;
            if (propertyElement != null) {
                //得到<property>的name属性值
                propertyName = propertyElement.getAttributeValue("name");
                //得到property的内容
                propertyRef = propertyElement.getAttributeValue("ref");
            }
            System.out.println("========================");
            System.out.println("id="+id);
            System.out.println("class="+classValue);
            System.out.println("propertyName="+propertyName);
            System.out.println("propertyRef="+propertyRef);
            System.out.println("========================");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

测试结果:

 2. 反射机制:对配置文件中的类名使用反射机制可以实现类加载初始化等工作,也可以调用类的方法进行属性注入,java.lang.reflect提供了反射相关的工具

public class TestReflect {
    public static void main(String[] args) {
        //表示StudentDao接口全路径
        String studentDao = "com.IOC.dao.StudentDao";
        //表示StudentService接口全路径
        String studentService = "com.IOC.service.StudentService";
        //表示StudentDaoImpl类全路径
        String studentDaoImpl = "com.IOC.dao.impl.StudentDaoImpl";
        //表示StudentServiceImpl
        String studentServiceImpl = "com.IOC.service.impl.StudentServiceImpl";
        //表示StudentAction类全路径
        String studentAction = "com.IOC.action.StudentAction";

        //表示setStudentService方法的字符串
        String setStudentService = "setStudentService";
        //表示setStudentDao方法的字符串
        String setStudentDao = "setStudentDao";
        try {
            //使用全路径字符串加载StudentDao类别
            Class studentDaoClass = Class.forName(studentDao);
            //使用全路径字符串加载StudentService类别
            Class studentServiceClass = Class.forName(studentService);
            //使用全路径字符串加载StudentDaoImpl类别
            Class studentDaoImplClass = Class.forName(studentDaoImpl);
            //使用全路径字符串加载StudentServiceImpl类别
            Class studentServiceImplClass = Class.forName(studentServiceImpl);
            //使用全路径字符串加载StudentAction类别
            Class studentActionClass = Class.forName(studentAction);

            //setStudentDao方法签名,相当于获取次此方法,使用类别获取setStudentDao方法
            Method setDaoMethod = studentServiceImplClass.getMethod(setStudentDao, studentDaoClass);
            //setStudentService方法签名,使用类别获取setStudentService方法
            Method setServiceMethod = studentActionClass.getMethod(setStudentService, studentServiceClass);

            //创建StudentDaoImpl对象,相当于new StudentDaoImpl(),但返回的是Object对象
            Object studentDaoImplnstance = studentDaoImplClass.newInstance();
            //创建StudentServiceImpl对象,相当于new StudentServiceImpl(),但返回的是Object对象
            Object studentServiceImplInstance = studentServiceImplClass.newInstance();
            //创建StudentAction对象,相当于new StudentAction(),但返回的是Object对象
            Object studentActionInstance = studentActionClass.newInstance();

            //使用反射机制调用StudentServiceImpl的setStudentDao方法,参数是StudentDaoImpl对象,
            //第一个参数是执行方法的类实例,第二个参数是方法参数
            setDaoMethod.invoke(studentServiceImplInstance, studentDaoImplnstance);
            setServiceMethod.invoke(studentActionInstance, studentServiceImplInstance);
            //调用StudentAction的printName方法
            ((StudentAction)studentActionInstance).printName();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

测试结果:

原文地址:https://www.cnblogs.com/yangjingru/p/12129264.html

时间: 2024-10-11 00:15:22

spring的ioc技术的相关文章

Spring之IOC容器注入

上一篇做了IOC和AOP的原理介绍,这一篇主要讲解IOC的注入.不过我依然困惑一个问题: 一 : 依赖注入(DI)中有三种注入方式,那Spring中到底实现了几种方式?也是三种? IOC在很多框架中都有实现,并不是Spring特有的,之前说过IOC主要包含DL(Dependency Lookup)和DI(Dependency Injection),也就是说实现IOC的技术有很多,但是主要包含DI和DL,但是相对而言,DI应用范围比较广泛,我想这也是为什么Martin Fowler将控制反转用依赖

Spring的Ioc

引用:http://www.cnblogs.com/xdp-gacl/p/4249939.html 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框架的IOC的理解以及谈谈我对Spring Ioc的理解. 一.分享Iteye的开涛对Ioc的精彩讲解 首先要分享的是Iteye的开涛这位技术牛人对Spring框

我理解的IOC技术在Java和C#中比较分析

一直想用心写这个系列的文章,其实看得越多,也就越觉得自己在这方面的功力太浅,也就越不想班门弄斧啦,作为一个开篇,我想把这个技术深层次化,在之前的.net的一个MVC系列文章其实已经涉及到了,只是.net在这方面的应用不如java来得这么猛烈,这么酣汗淋漓,所以也就下定决心,这一阶段针对这一个技术点进行深层次的剖析. IOC,英文全称Inversion of Control,中文直译控制反转,一般我们称之为“依赖注入”原则,在我还未过多涉足java领域时,在C#语言24个设计模式中(参见<大话设计

好莱坞原则—Spring的IOC容器

IOC容器的概念,之前在学习SSH的时候,就有接触过.但那时候也仅仅是知道这么个概念,认为它非常难理解.事实上并非它难理解,而是我并没有停下来好好对它总结梳理过. IOC(Inversion of Control)简单介绍: 控制反转",并非一种技术.而是一种思想.一种主动提供服务的思想.所谓IOC,就是由Spring负责控制对象的生命周期和对象间的关系,与我们传统的在对象内部直接控制背道而驰. 在传统的程序开发中,完毕一个业务逻辑至少须要两个或两个以上的对象协助完毕.通常一个对象要使用另外一个

Spring中IoC的入门实例

Spring中IoC的入门实例 Spring的模块化是很强的,各个功能模块都是独立的,我们可以选择的使用.这一章先从Spring的IoC开始.所谓IoC就是一个用XML来定义生成对象的模式,我们看看如果来使用的. 数据模型 1.如下图所示有三个类,Human(人类)是接口,Chinese(中国人)是一个子类,American(美国人)是另外一个子类. 源代码如下: package cn.com.chengang.spring;public interface Human {void eat();

Spring的IoC应用

IoC(Inversion of Control,控制反转) Spring的IoC应用是其框架的最大的特点,通过依赖注入可以大大降低代码之间的耦合度,从而实现代码和功能之间的分离.在代码中可以不直接和对象及服务器进行连接,但是在配置中说明哪一个组件需要哪一项任务,容器会负责将其联系起来.使用反向控制,对象被动接收依赖类而不是自己去创建或者查找其所依赖的对象. 在介绍Spring 的依赖注入之前,首先来看一个简单的Java应用: 改示例包含四个文件:一个是Person接口类,一个是Student类

Spring中IOC和AOP的详细解释

我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入,和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式. IOC就是典型的工厂模式,通过sessionfactory去注入实例. AOP就是典型的代理模式的体现. 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对

浅谈Spring与IOC

1.什么是Spring Spring是一个开源的轻量级的应用开发框架,目的是为了简化企业级编程,降低各个模块之间的侵入性和耦合度 Spring 提供了IOC和AOP的功能,可以将组建的耦合度降低,便于日后的维护和升级,实现各个模块的组件化编程. 为什么要用Spring? Spring的本质是管理软件中的对象,就是创建对象和维护对象之间的关系 2.Spring容器 Spring容器的理解就是在Spring中,任何的Java和JavaBean都被当成Bean处理,这是bean都交给Spring容器管

Spring的IOC理解(转载)

学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring框架的IOC的理解以及谈谈我对Spring Ioc的理解. 一.分享Iteye的开涛对Ioc的精彩讲解 首先要分享的是Iteye的开涛这位技术牛人对Spring框架的IOC的理解,写得非常通俗易懂,以下内容全部来自原文,原文地址:http://jinniansh