array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 spring入门学习第二篇 - 爱码网

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>

结束!

 

 

相关文章: