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>

结束!

 

原文地址:https://www.cnblogs.com/liweixml/p/11697527.html

时间: 2024-10-08 00:27:46

spring入门学习第二篇的相关文章

spring入门学习第一篇

本篇知识点有:maven依赖,applicationContext.xml配置文件,Scope作用域,初始化和销毁,延时初始化lazy-init,工厂Factory,Aware接口,动态bean.内容可能过多,建议准备好瓜子可乐,不足之处,多多指正. 1.maven依赖 因为我们使用的是maven + spring-context学习的,所以在使用spring之前,我们要先把maven依赖导入进来,导入spring-context5.2.0.RELEASE版本. 导入代码如下: <depende

UI学习第二篇 (控件)

UIbutton 也是一个控件,它属于UIControl 用的最多的就是事件响应 1. //创建按钮对象 UIButton * _botton = [UIButton buttonWithType:UIButtonTypeCustom]; //设置标题 [_botton setTitle:@"按住说话" forstate:UIControlStateNormal]; [_botton setTitle:@"松开说话" forstate:UIControlStateH

Web前端学习第二篇

今天看到了一篇写的不错的文章,是有关对JQuery.js等一些源代码初识的内容,感觉写的还是不错,所以拿过来分享一下. 文章的地址:http://my249645546.iteye.com/blog/1716629 1.对(function(){})(); 几乎所有的开源js代码开篇都是这样(function(……){……})(……); 下面是Jquery的部分源码: (function( window, undefined ) { var jQuery = function( selector

Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍

Java并发包下锁学习第二篇队列同步器 还记得在第一篇文章中,讲到的locks包下的类结果图吗?如下图: ? 从图中,我们可以看到AbstractQueuedSynchronizer这个类很重要(在本文中,凯哥就用AQS来代替这个类).我们先来了解这个类.对这个类了解之后,学习后面的会更容易了. 本篇是<凯哥(凯哥Java:kagejava)并发编程学习>系列之<Lock系列>教程的第一篇:<Java并发包下锁学习第二篇:队列同步器>. 本文主要内容:同步器介绍:同步器

PHP入门学习——函数篇

本文来源:http://www.zretc.com/technologyDetail/442.html 要进行PHP入门学习,函数就是一个必会的东西了,下面这些你需要了解: 一. 函数的定义 //函数定义 function函数名([参数1,参数2,参数3,--]){ 函数体: [return返回值:] } //函数调用 函数名([参数1,参数2,参数3,--]); 例如: //定义函数sum functionsum($a,$b){ $sum_value=$a+$b; return$sum_val

Python学习笔记之入门(第二篇)

1.第一个Python代码 在Linux下/home/zx 目录下新建hello.py文件 1 #vim hello.py //添加如下内容 2 3 #!/usr/bin/env python 4 5 # -*- coding:utf-8 -*- 6 print "Hello,World" 7 8 #chmod +x hello.py //添加执行权限 执行代码: ./hello.py 结果: python内部执行过程如下:   python首先把hello.py文件读到内存当中,然后

Spring入门学习(一)

今天开始正式学习Spring框架,首先讲安装,spring 的版本发布中,有的版本有同步发布依赖包的下载,有的却没有.3.0.2的版本有, 而3.2.3 的版本却没有(可能是因为依赖库没有改变的缘故). 1.下载Spring 这里只是为了学习,下载3.0.2版本的:http://s3.amazonaws.com/dist.springframework.org/release/SPR/spring-framework-3.0.2.RELEASE-dependencies.zip 2.配置Spri

Android基础学习第二篇—Activity

写在前面的话: 1. 最近在自学Android,也是边看书边写一些Demo,由于知识点越来越多,脑子越来越记不清楚,所以打算写成读书笔记,供以后查看,也算是把自己学到所理解的东西写出来,献丑,如有不对的地方,希望大家给与指正. 2. 由于类似于读书笔记,可能格式神马的会比较随(hen)意(chou),大家看着受不了,可以使劲吐槽. *************************************我只是分割线***************************************

Python 入门学习第二部分:

一.初识模块 Pyhon具有非常丰富和强大的标准库与第三方库,几乎能实现你想要的任何功能.python中的模块分为两种类型,一种是标准库,不需要了另外安装,直接在写程序的时候通过import指令导入就行:还有一种是第三方库,必须要下载安装到对应的文件目录下,才能使用.具体的呢下面最下简单的介绍. 1.两个例子 1)Sysm模块 当运行如下代码的时候,sys的path功能输出的结果是python 的全局环境变量,即python调用该模块时进行索引的路径.argv的功能则是打印模块的相对位置,同时可