zoukankan      html  css  js  c++  java
  • spring入门学习第二篇

    依赖注入IOC

    IOC:inverse of control:控制反转

    2004年,Martin Fowler探讨了同一个问题,既然IOC是控制反转,那么到底是“哪些方面的控制被反转了呢?”,经过详细地分析和论证后,他得出了答案:“获得依赖对象的过程被反转了”。控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,他给“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。他的这个答案,实际上给出了实现IOC的方法:注入。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。

     

    依赖注入:spring管理的bean,当它依赖一个被其他spring管理的bean的时候,spring负责把它注入进来

    注入方式

    1、构造函数注入(Constructor)

    2、属性注入(setter)

    3、接口注入(比较少用)

    案例一:

    EmpDao接口:

    package com.complex;
    
    public interface EmpDao {
        void insert();
    }

    EmpDaoImpl实现类:

    package com.complex;
    
    public class EmpDaoImpl implements EmpDao{
    
        @Override
        public void insert() {
            System.out.println("this is EmpDao Method insert");
        }
    }

    EmpService接口:

    package com.complex;
    
    public interface EmpService {
        void insert();
    }

    EmpServiceImpl实现类:

    package com.complex;
    
    public class EmpServiceImpl implements EmpService{
        private EmpDao empDao;
    
        public EmpServiceImpl(){}
    
        //构造函数注入
        public EmpServiceImpl(EmpDao empDao){ this.empDao = empDao;}
    
        @Override
        public void insert() {
            empDao.insert();
        }
    }

    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.xsd">
    
        <bean id="empDaoImpl" class="com.complex.EmpDaoImpl"></bean>
    
        <bean id="empServiceImpl" class="com.complex.EmpServiceImpl">
            <!--可以看到我们通过构造函数注入,实现了在实例化bean的时候会将empDaoImpl这个bean自动注入到empServiceImpl这个bean的构造函数中实例化bean-->
            <constructor-arg ref="empDaoImpl"></constructor-arg>
        </bean>
    </beans>

    Main测试:

    package com.complex;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext_complex.xml");
            EmpServiceImpl empServiceImpl = context.getBean("empServiceImpl", EmpServiceImpl.class);
            empServiceImpl.insert();
        }
    
    }

    测试结果:this is EmpDao Method insert

    我们通过依赖注入实现了在实例化Bean的时候通过构造函数注入EmpDao

    为什么EmpServiceImpl放EmpDao接口类型,因为这样遵循依赖倒转原则:抽象不应该依赖于细节,细节应该依赖于抽象。

     

    依赖注入详解

    1、如何实现多个属性通过构造器注入

    BookInfo类

    package com.basic;
    
    import java.math.BigDecimal;
    
    public class BookInfo {
        private int id;
        private String name;
        private BigDecimal price;
        private int count;
    
        public BookInfo(int id, String name, BigDecimal price, int count) {
            this.id = id;
            this.name = name;
            this.price = price;
            this.count = count;
        }
    }

    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.xsd">
        <bean id="bookInfo" class="com.basic.BookInfo">
            <constructor-arg name="id" value="1"></constructor-arg>
            <constructor-arg name="name" value="童话故事"></constructor-arg>
            <constructor-arg name="price" value="15"></constructor-arg>
            <constructor-arg name="count" value="100"></constructor-arg>
        </bean>
    </beans>
    通过构造器注入我们可以指定构造参数,spring是如何知道要传的参数是哪个呢?
    
    constructor-arg给我们提供了三种指定参数名的方法
    
    name:设置参数名
    
    index:设置参数索引
    
    type:参数类型
    
    如果不设置的话,spring会依据先后顺序一个个传参进去。

    2、如何通过属性注入?

    BookInfo类

    package com.basic;
    
    import java.math.BigDecimal;
    
    public class BookInfo {
        private int id;
        private String name;
        private BigDecimal price;
        private int count;
    
        //get和set方法,这里省略了
    }

    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.xsd">
        <bean id="bookInfo" class="com.basic.BookInfo">
            <property name="id" value="1"></property>
            <property name="name" value="童话故事"></property>
            <property name="price" value="15"></property>
            <property name="count" value="100"></property>
        </bean>
    </beans>

    通过设置property实现属性注入,name指定对应的属性。

    3、复杂类型如何注入?

    前面我们实现的是简单的类型,那么问题来了,复杂类型如何注入?例如list,map,实体类等等

    ShopCar

    package com.basic;
    
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    public class ShopCar {
        private String sname;   //基本类型
        private List<BookInfo> list;    //list集合
        private Map<Integer,BookInfo> map;  //map集合
        private Set<BookInfo> bookInfoSet;  //set集合
        private BookInfo bookInfo;  //实体对象
    
        public ShopCar(String sname, List<BookInfo> list, Map<Integer, BookInfo> map, Set<BookInfo> bookInfoSet, BookInfo bookInfo) {
            this.sname = sname;
            this.list = list;
            this.map = map;
            this.bookInfoSet = bookInfoSet;
            this.bookInfo = bookInfo;
        }
        
        //set和get方法,这里省略了....太长了
    }

    先来看看构造函数注入复杂类型

    <?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 id="bookInfo" class="com.basic.BookInfo">
            <constructor-arg name="id" value="1"></constructor-arg>
            <constructor-arg name="name" value="童话故事"></constructor-arg>
            <constructor-arg name="price" value="15"></constructor-arg>
            <constructor-arg name="count" value="100"></constructor-arg>
        </bean>
    
        <bean id="shopCar" class="com.basic.ShopCar">
    <!--        普通类型一样用value-->
            <constructor-arg name="sname" value="购物车1"></constructor-arg>
    <!--        实体类用ref-->
            <constructor-arg name="bookInfo" ref="bookInfo"></constructor-arg>
    <!--        list类型设置-->
            <constructor-arg name="list">
                <list>
                    <ref bean="bookInfo"></ref>
                    <bean class="com.basic.BookInfo">
                        <property name="id" value="2"></property>
                        <property name="name" value="小红帽"></property>
                        <property name="price" value="15"></property>
                        <property name="count" value="100"></property>
                    </bean>
                </list>
            </constructor-arg>
    <!--        map设置-->
            <constructor-arg name="map">
                <map>
                    <entry key="1" value-ref="bookInfo"></entry>
                </map>
            </constructor-arg>
    <!--        set设置-->
            <constructor-arg name="bookInfoSet">
                <set>
                    <ref bean="bookInfo"></ref>
                </set>
            </constructor-arg>
        </bean>
    </beans>

    复杂类型属性注入

    <?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 id="bookInfo" class="com.basic.BookInfo">
            <constructor-arg name="id" value="1"></constructor-arg>
            <constructor-arg name="name" value="童话故事"></constructor-arg>
            <constructor-arg name="price" value="15"></constructor-arg>
            <constructor-arg name="count" value="100"></constructor-arg>
        </bean>
    
        <bean id="shopCar" class="com.basic.ShopCar">
            <!--        基本类型-->
            <property name="sname" value="shop2"></property>
    <!--        实体类型-->
            <property name="bookInfo" ref="bookInfo"></property>
    <!--        list类型-->
            <property name="list">
                <list>
                    <ref bean="bookInfo"></ref>
                </list>
            </property>
    <!--        map类型-->
            <property name="map">
                <map>
                    <entry key="1" value-ref="bookInfo"></entry>
                </map>
            </property>
    <!--        set类型-->
            <property name="bookInfoSet">
                <set>
                    <ref bean="bookInfo"></ref>
                </set>
            </property>
        </bean>
    </beans>

    结束!

     
  • 相关阅读:
    个人冲刺6
    个人冲刺5
    个人冲刺4
    学习进度10
    个人冲刺3
    个人冲刺2
    单词统计
    返回一个整数数组中最大子数组的和
    JavaWeb_JavaEE_命名规则 转载http://www.cnblogs.com/xwdreamer/
    软件工程作业(四则运算web界面实现)-3
  • 原文地址:https://www.cnblogs.com/liweixml/p/11697527.html
Copyright © 2011-2022 走看看