zoukankan      html  css  js  c++  java
  • 初识Spring框架实现IOC和DI(依赖注入)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,

    IoC是什么

      Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。

      在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

      ●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

      ●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

      用图例说明一下,传统程序设计如图2-1,都是主动去创建相关对象然后再组合起来:

                                    

    当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图2-2所示:

                                           

    以上就是简单的IOC的理解

    那么接下来我们就来实现下我们自己的第一个Spring示例

    1.1我们准备一个HelloWord类

    package cn.ljy.clazz;
    
    public class HelloWord {
        //名称
        private String name;
        //性别
        private String sex;
        //年龄
        private int age;
        //体重
        private double weight;
        
        
        //准备构造函数
        
        //无参构造   初始化IOC容器时需要
        public HelloWord() {
            
        }
    
        //姓名   性别   年龄的构造
        public HelloWord(String name, String sex, int age) {
            this.name = name;
            this.sex = sex;
            this.age = age;
        }
    
        //姓名  性别   体重的构造
        public HelloWord(String name, String sex, double weight) {
            this.name = name;
            this.sex = sex;
            this.weight = weight;
        }
    
        public String sayHello(){
            return "HelloWord"+name;
        }
        
        
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "HelloWord [name=" + name + ", sex=" + sex + ", age=" + age
                    + ", weight=" + weight + "]";
        }
        
    }    

    1.2我们必须得准备一个applicationContext.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"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util  
            http://www.springframework.org/schema/util/spring-util-3.1.xsd
            ">
       <!-- 将 HelloWord 类交给Spring容器进行管理-->
       <!-- 通过属性的方式传入参数 -->
       <bean id="HelloWord" class="cn.ljy.clazz.HelloWord">
               <!-- 为参数赋值 -->
               <property name="name" value="巴黎的雨季"></property>
       </bean>
    </beans>  

     这样就整理好了第一个配置文件了,然后我们进行一道测试

    package cn.ljy.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.ljy.clazz.HelloWord;
    import cn.ljy.clazz.NewPeople;
    import cn.ljy.clazz.People;
    import cn.ljy.clazz.Person;
    
    public class MyTest {
        public static void main(String[] args) {
            //实例化Spring容器的上下文  (创建IOC容器)
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
            //通过ApplicationContext的getBean()方法,根据id来获取Bean的实例
            HelloWord hello = (HelloWord)context.getBean("HelloWord");
            //调用HelloWord类中的方法
            System.out.println("通过属性的方式给name赋值:");
            String result = hello.sayHello();
            System.out.println(result);
            
    }

    实现结果为:

     1.3以上在配置文件中使用的是setter方法依赖注入,接下来我们使用构造器的方式来实现依赖注入

    applicationContext.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"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util  
            http://www.springframework.org/schema/util/spring-util-3.1.xsd
            ">
       <!-- 将 HelloWord 类交给Spring容器进行管理-->
       <!-- 通过构造器的方式传入参数 -->
       <bean id="AttributeByConstructor1" class="cn.ljy.clazz.HelloWord">
               <!-- 通过构造器方式传参 -->
               <constructor-arg value="巴黎的雨季" index="0"/>
               <constructor-arg value="" index="1"/>
               <constructor-arg value="18" type="int"/>
       </bean>
    </beans>  

     

    执行结果如图

    1.4使用引用类型,引用自定义的Bean(外部Bean)

    准备一个person对象

    package cn.ljy.clazz;
    
    public class Person {
        private String name;
        private int age;
        private Car car;    
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public Car getCar() {
            return car;
        }
        public void setCar(Car car) {
            this.car = car;
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
        }
        
        
    }

    applicationContext.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"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util  
            http://www.springframework.org/schema/util/spring-util-3.1.xsd
            ">
      
      
         <!-- 监管Car 准备三car-->
       <bean id="car" class="cn.ljy.clazz.Car">
               <property name="brand" value="奔驰"></property>
               <property name="business" value="上海"></property>
               <property name="price" value="300000"></property>
       </bean>
    
    
        <!-- 配置person  引用Car -->
       <bean id="person" class="cn.ljy.clazz.Person">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="18"></property>    
               <property name="car" ref="car"></property>
       </bean>
       </bean>
    </beans>  

     

    执行结果

    1.5使用内部Bean

    <!-- 内部bean   -->
        <bean id="person2" class="cn.ljy.clazz.Person">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="18"></property>    
               <!-- 注意:内部bean只能在内部使用,不能被外部所引用 -->
               <property name="car" >
                   <bean class="cn.ljy.clazz.Car">
                       <property name="brand" value="福特"></property>
                       <property name="business" value="北京"></property>
                       <property name="price" value="400000"></property>
                   </bean>
               </property>
       </bean>

    执行结果与上一步基本一致

    1.6配置list集合属性

    People

    package cn.ljy.clazz;
    
    import java.util.List;
    
    public class People {
        
        private String name;
        private int age;
        private List<Car> cars;
        
        
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public List<Car> getCars() {
            return cars;
        }
        public void setCars(List<Car> cars) {
            this.cars = cars;
        }
        @Override
        public String toString() {
            return "People [name=" + name + ", age=" + age + ", cars=" + cars + "]";
        }
        
        
    }
    <!-- list集合属性的配置 -->
       <bean id="people" class="cn.ljy.clazz.People">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="28"></property>    
               <property name="cars">
                   <!-- 使用list节点为集合属性赋值 -->
                   <list>
                       <ref bean="car"/>
                       <ref bean="car2"/>
                       <ref bean="car3"/>
                   </list>
               </property>
       </bean>

     

    执行结果

    1.7使用Map集合配置属性

    NewPeople

    package cn.ljy.clazz;
    
    import java.util.Map;
    import java.util.Properties;
    
    
    
    public class NewPeople {
        private String name;
        private int age;
        private Map<String,Car> cars;
        
        //配置properties属性
        private Properties properties;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public Map<String, Car> getCars() {
            return cars;
        }
        public void setCars(Map<String, Car> cars) {
            this.cars = cars;
        }
        
        public Properties getProperties() {
            return properties;
        }
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
        @Override
        public String toString() {
            return "NewPeople [name=" + name + ", age=" + age + ", cars=" + cars
                    + "]";
        }
        
        
    }
     <!--Map集合属性值的配置  -->
       <bean id="people2" class="cn.ljy.clazz.NewPeople">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="28"></property>    
               <property name="cars">
                   <map>
                       <entry key="OneCar" value-ref="car"></entry>
                       <entry key="TwoCar" value-ref="car2"></entry>
                       <entry key="Three">
                           <bean class="cn.ljy.clazz.Car">
                               <property name="brand" value="法拉利"></property>
                               <property name="business" value="上海"></property>
                               <property name="price" value="4000000"></property>
                           </bean>
                       </entry>
                   </map>
               </property>
       </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"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:util="http://www.springframework.org/schema/util"
        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/aop
            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
            http://www.springframework.org/schema/util  
            http://www.springframework.org/schema/util/spring-util-3.1.xsd
            http://www.springframework.org/schema/context
             http://www.springframework.org/schema/context/spring-context-3.0.xsd
            ">
            
         
            
       <!-- 将 HelloWord 类交给Spring容器进行管理-->
       
       <!-- 通过属性的方式传入参数 -->
       <bean id="HelloWord" class="cn.ljy.clazz.HelloWord">
               <!-- 为参数赋值 -->
               <property name="name" value="巴黎的雨季"></property>
       </bean>
       
       <!-- 通过构造器的方式传入参数 -->
       <bean id="AttributeByConstructor1" class="cn.ljy.clazz.HelloWord">
               <!-- 通过构造器方式传参 -->
               <constructor-arg value="巴黎的雨季" index="0"/>
               <constructor-arg value="" index="1"/>
               <constructor-arg value="18" type="int"/>
       </bean>
       
       <!--给第二个构造器赋值  -->
       <bean id="AttributeByConstructor2" class="cn.ljy.clazz.HelloWord">
               <!-- 通过构造器方式传参 -->
               <constructor-arg value="巴黎的雨季" index="0"/>
               <constructor-arg name="sex" value=""  />
               <constructor-arg value="130"  type="double"/>
       </bean>
    
       <!-- 监管Car 准备三car-->
       <bean id="car" class="cn.ljy.clazz.Car">
               <property name="brand" value="奔驰"></property>
               <property name="business" value="上海"></property>
               <property name="price" value="300000"></property>
       </bean>
       <bean id="car2" class="cn.ljy.clazz.Car">
               <property name="brand" value="大众"></property>
               <property name="business" value="广州"></property>
               <property name="price" value="120000"></property>
       </bean>
       <bean id="car3" class="cn.ljy.clazz.Car">
               <property name="brand" value="雪佛兰"></property>
               <property name="business" value="深圳"></property>
               <property name="price" value="150000"></property>
       </bean>
       
       <!-- 配置person  引用Car -->
       <bean id="person" class="cn.ljy.clazz.Person">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="18"></property>    
               <property name="car" ref="car"></property>
       </bean>
       
       <!-- 内部bean   -->
        <bean id="person2" class="cn.ljy.clazz.Person">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="18"></property>    
               <!-- 注意:内部bean只能在内部使用,不能被外部所引用 -->
               <property name="car" >
                   <bean class="cn.ljy.clazz.Car">
                       <property name="brand" value="福特"></property>
                       <property name="business" value="北京"></property>
                       <property name="price" value="400000"></property>
                   </bean>
               </property>
       </bean>
       
       <!-- 级联属性的使用 -->
       <bean id="person3" class="cn.ljy.clazz.Person">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="18"></property>    
               <property name="car" ref="car"></property>
               <!-- 级联,改变原来的值    注意:必须是存在car对象才可以,Spring不会自动的创建car -->
               <property name="car.brand" value="劳斯莱斯"></property>
       </bean>
       
       
       <!-- list集合属性的配置 -->
       <bean id="people" class="cn.ljy.clazz.People">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="28"></property>    
               <property name="cars">
                   <!-- 使用list节点为集合属性赋值 -->
                   <list>
                       <ref bean="car"/>
                       <ref bean="car2"/>
                       <ref bean="car3"/>
                   </list>
               </property>
       </bean>
       
       <!--Map集合属性值的配置  -->
       <bean id="people2" class="cn.ljy.clazz.NewPeople">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="28"></property>    
               <property name="cars">
                   <map>
                       <entry key="OneCar" value-ref="car"></entry>
                       <entry key="TwoCar" value-ref="car2"></entry>
                       <entry key="Three">
                           <bean class="cn.ljy.clazz.Car">
                               <property name="brand" value="法拉利"></property>
                               <property name="business" value="上海"></property>
                               <property name="price" value="4000000"></property>
                           </bean>
                       </entry>
                   </map>
               </property>
       </bean>
       
       <!-- 配置properties属性-->
       <bean id="people3" class="cn.ljy.clazz.NewPeople">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="28"></property>    
               <property name="properties">
                   <props>
                       <prop key="user">root</prop>
                       <prop key="password">123</prop>
                       <prop key="jdbcurl">jdbc:mysql:/test</prop>
                       <prop key="drivarClass">com.mysql.jdbc.java</prop>
                   </props>
               </property>
       </bean>
       
       
       <!-- 独立出一个bean  比如说list 需要引入新的命名空间  util-->
      <!-- <util:list id="cars">
               <ref bean="car"/>
               <ref bean="car2"/>
               <ref bean="car3"/>
       </util>
       
       <bean id="people4" class="cn.ljy.clazz.People">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="28"></property>    
               <property name="cars" ref="cars"></property>
       </bean>  -->
      
      
      
       <!-- 自动装配
               可以使用autowire属性指定自动装配的方式
               byName 根据Bean的名字和当前Bean的setter风格的属性名进行自动装配,若有匹配的,则进行自动装配 ,若没有匹配的则不进行装配 
               byType 根据Bean的类型和当前Bean的属性的类型进行自动装配,若IOC容器中定义了多个类型匹配的Bean 则会抛出异常
        -->
        <bean id="person4" class="cn.ljy.clazz.Person" autowire="byName">
               <property name="name" value="巴黎的雨季"></property>
               <property name="age" value="18"></property>    
       </bean>
       
       
       
    </beans>  
  • 相关阅读:
    spawn-fcgi
    JSP EL表达式
    关于订阅号和自定义菜单的关系问题
    微信公众平台开发(74) 用户分组管理
    微信公众平台开发(73) 客服接口发送客服消息
    用数据分析寻找下一位苍井空
    微商城
    微信支付体验
    微信公众平台开发(72)第三方接口
    微信公众平台开发(71)OAuth2.0网页授权
  • 原文地址:https://www.cnblogs.com/liujiayun/p/5867953.html
Copyright © 2011-2022 走看看