zoukankan      html  css  js  c++  java
  • IoC: 控制反转

    :将传统的由程序代码直接操控对象的调用权交给容器.通过容器控制对象的装配及生命周期管理.

    (一下这两段话摘自http://blog.csdn.net/m13666368773/article/details/7802126)

    IOC中最基本的技术就是“反射(Reflection)”编程,目前.Net C#JavaPHP5等语言均支持,其中PHP5的技术书籍中,有时候也被翻译成“映射”。有关反射的概念和用法,大家应该都很清楚,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象。这种编程方式可以让对象在生成时才决定到底是哪一种对象。反射的应用是很广泛的,很多的成熟的框架,比如象Java中的hibernateSpring框架,.Net中 NHibernateSpring.NET框架都是把“反射”做为最基本的技术手段。

    我们可以把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言的的反射编程,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。

    控制反转的两种实现方式:

    1.依赖查找(DL)

    2.依赖注入(DI): 程序在运行时,若需要调用另一个对象协助,无需在代码中创建而是依赖外部容器,由容器创建后传递给程序.

    依赖注入是最优秀的解耦方式,依赖注入让Springbean 之间以配置文件方式组织在一起而不是硬编码的方式.

    控制反转Demo1:
    /*dao层接口*/
    public interface IStudentDao {
        public void selectStudent(int cid);
    }
    /*dao层实现类*/
    public class StudentDaoImpl implements IStudentDao {
        public StudentDaoImpl() {
            super();
            System.out.println("构造函数执行!");
        }
        @Override
        public void selectStudent(int cid) {
            System.out.println("查找学生"+cid);
        }
    /*Sping配置文件中注册实现类bean*/
    <?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.xsd">
        <!-- bean definitions here -->
            <bean id="sdImpl" class="com.xiehe.dao.StudentDaoImpl"/>
    </beans>
    /*测试类中*/
    public class MyTest {
        @Test
        public void test01(){
            //1.获取容器
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationSpring.xml");
            //2.从容器中获取对象
            IStudentDao sdImpl = (IStudentDao) context.getBean("sdImpl");
            sdImpl.selectStudent(1);
        }
     :结果截图
    
     本例中可以明显看出,在测试类中获取StudentDaoImpl 是通过容器(调用了构造)而不是依赖于StudentDaoImpl 
     

    ApplicationContext 用于加载Spring 配置文件,在程序中充当容器.其实现类有两

    a)基于xml的注入:

    Bean的初始化由容器完成称为注入.根据注入方式不同分为 设值注入 和 构造注入

    1)设值注入 通过setter 方法传入被调用者的实例中

    2)构造注入 调用构造函数完成注入

    /*实体类:schol*/
    public class School {
        private String name;
        private String addr;
        public School(String name, String addr) {
            super();
            this.name = name;
            this.addr = addr;
        }
        public School() {
            super();
        }
    Getter/setter
    }
    /*实体类:Student*/
    public class Student {
        private String name;
        private int age;
        private School mySchool;
        public Student() {
            super();
        }
        public Student(String name, int age, School mySchool) {
            super();
            this.name = name;
            this.age = age;
            this.mySchool = mySchool;
        }
    Getter/setter
    }
    /*spring配置文件*/
    <?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.xsd">
    <!-- bean definitions here -->
        <!-- 设值注入 -->
            <bean id="mySchool" class="com.xiehe.dao.School">
                <property name="name" value="北京大学"></property>
                <property name="addr" value="海淀区"></property>
            </bean>
            <!-- 设值注入 -->
            <bean id="sdImpl" class="com.xiehe.dao.Student" >
                <property name="name" value="张赛"/>
                <property name="age" value="58"/>
                <!-- 域类型注入方式1:-- >
                <!-- <property name="mySchool" ref="mySchool"/> -->
                <!-- 域类型注入方式2:-- >
                <property name="mySchool">
                    <ref bean="mySchool"/>
                </property>
            </bean>
            <!-- 构造注入 -->
            <bean id="sdImpl2" class="com.xiehe.dao.Student">
                <constructor-arg name="name" value="张赛"/>
                <constructor-arg name="age" value="58"/>
                <constructor-arg name="mySchool" ref="mySchool"/>
            </bean>    
    </beans>
    /*测试类*/
    public class MyTest {
        @Test
        public void test01(){
            //1.获取容器
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationSpring.xml");
            //2.从容器中获取对象(设值注入)
            Student dao = (Student) context.getBean("sdImpl");
            System.out.println(dao);    
        }
        @Test
        public void test02(){
            //1.获取容器
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationSpring.xml");
            //2.从容器中获取对象(构造注入)
            Student dao = (Student) context.getBean("sdImpl2");
            System.out.println(dao);    
        }
    }
    
     

    Test01 结果截图:
    Test02 结果截图:

    b)基于注解的注入:

         在Spring 配置文件中添加组件扫描器:

    <context:component-scan base-package="com.xiehe.dao"/>

     在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的Java文件,如果扫描到有@Component (普通bean)@Controller(控制器)@Service(服务器)等这些注解的类,则把这些类注册为bean.

    /*注解式注入 */
    @Component("school1")
    public class School {
        @Value("清华大学")
        private String name;
        @Value("海淀区")
        private String addr;
    }
    /*注解式注入*/
    @Component(value="stu1")
    public class Student {
        @Value("张嘴")
        private String name;
        @Value("44")
        private int age;
        //默认 byType
        @Autowired
        private School mySchool;
    }
    /*spring 配置文件*/
    <?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.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- bean definitions here -->
        <!-- 配置组件扫描器 -->
        <context:component-scan base-package="com.xiehe.dao"/>    
    </beans>    
    /*测试类*/
    public class MyTest {
        @Test
        public void test01(){
            //1.获取容器
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/xiehe/dao/applicationSpring.xml");
            //2.从容器中获取对象
            Student dao = (Student) context.getBean("stu1");
            System.out.println(dao);
        }
    }
    

    运行截图:

  • 相关阅读:
    UI界面思想
    ARM汇编语言(3)(寄存器读写控制外设)
    ARM汇编(2)(指令)
    ARM汇编语言(1)(基本概念)
    QT软件初次使用中遇到的若干问题及思考
    webpack4打包html中img后src为“[object Module]”问题(已解决)
    gulp dev报错:ReferenceError:primordials is not defined(已解决)
    Ubuntu20.04安装yarn报错gpg: can't connect to the agent: IPC connect call failed(已解决)
    手摸手教程之ubuntu20.04更改国内镜像源(附其他版本ubuntu换源教程,最新详细教程)
    Alert提示框的vue组件编写
  • 原文地址:https://www.cnblogs.com/he-shao/p/6093347.html
Copyright © 2011-2022 走看看