Spring框架-2(IOC上)

Spring系列文章

Spring框架-1(基础)
Spring框架-2(IOC上)
Spring框架-3(IOC下)
Spring框架-4(AOP)
Spring框架-5(JDBC模板&Spring事务管理)
Spring框架-6(SpringMvc)
Spring框架-7(搭建SSM)
Spring框架-8(SpringMVC2)

前言

在上一篇文章我们已经梳理了一下spring框架的基础知识内容。接下来我们来分析和实践一下IOC吧!研究研究IOC的原理,看看IOC怎么使用。

首先看下我们需要学习一些什么吧!如下图:

IOC1.png

为什么叫控制反转?

传统控制

假设我需要两个资源,那么我们是怎么做的呢?ZiYuan ziYuan =new ZiYuan();然后我拿到了资源对象。

传统控制.png

Spring控制反转

那么在Spring当中我需要资源是怎么玩的呢?

  • 在我们项目中是给这个类写一个注解,例如@controller,@Component等。然后编写一个Spring的配置文件,Spring就会直接扫描指定的包名创建指定的对象。我需要使用就写一个注解注入,然后就可以直接调用资源了。当然这有点抽象,具体后面会详细分析。
  • 那么在最原始的方法是,在配置文件当中直接配置我的资源,然后spring读取配置文件中信息,创建指定资源。如下图:
Spring控制反转简略图.png

编写IOC快速入门程序

1.创建工程

创建一个web项目工程,导入Spring所需要的jar包,这里我用的IDEA。最简单的方法如下图,一直下一步下一步就好了。如果你使用eclipse你可以去Spring官网下载相应的jar包

创建工程.png

2.需求和代码编写

需求

我们通过使用xml的方式来创建一个对象(资源)并使用这个资源。

创建一个类
public class MyService {
    public void showTest() {
        System.out.println("这是一个测试语句");
    }
}

3.创建一个配置文件,配置我们的测试类

配置文件名称为:applicationContext.xml
,注意配置文件需要再src目录结构下。
代码如下:

<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="userService" class="com.zhong.springdemo.MyServiceImpl"/>
</beans>

可以看到我们的xml里面的bean配置了一个id 和Class。

  • id:我们后面需要用到的。
  • class:配置我们需要交给spring管理的资源对象的全路径名称

4.使用我们交给Spring管理的资源

传统方式使用:
 MyService myService=new MyService();
        myService.showTest();
使用Spring:
    public static void main(String[] args) {
        // 使用ApplicationContext工厂的接口,使用该接口可以获取到具体的资源对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //在工厂中通过配置的id来获得我需要的资源对象
        MyService myService = (MyService) applicationContext.getBean("userService");
        myService.showTest();
    }

输出结果就不用写了,就是打印出来一句话。好的,这个入门程序已经完成,过程非常的简单。

  1. 写了一个资源
  2. 用xml配置
  3. 然后使用ApplicationContext工厂的接口创建指定对象
  4. 再通过我配置好的id获取对象,调用资源

入门程序2

刚才我们体验了一把Spring的工厂和创建对象,那么接下来我们把升级一下;

需求

我有一个controller,我需要把service注入到controller中。再调用service方法。

1.建类
public class MyController {
    //通过spring把myService注入到这个资源内
    private MyService myService;

    //必须写一个set方法,spring框架解析配置文件通过set方法注入
    public void setMyService(MyService myService) {
        this.myService = myService;
    }

    //测试
    public void test() {
        myService.showTest();
    }
}

2.修改配置文件

  1. 首先需要把controller配置
  2. 通过配置文件将service注入到controller中
  3. 给service中的属性注入值
<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="userService" class="com.zhong.springdemo.MyService">
        <!--给textStr属性注入值-->
        <property name="textStr" value="这是一个测试的语句"/>
    </bean>

    <bean id="userController" class="com.zhong.springdemo.MyController">
        <!--把MyService注入到controller中-->
        <property name="myService" ref="userService"/>
    </bean>
</beans>

3.运行测试

 public static void main(String[] args) {
        // 使用Spring的工厂:
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 通过工厂获得类:
        MyController myController = (MyController) applicationContext.getBean("userController");
        myController.test();

    }

结果打印出来:这是一个测试的语句

非常的简单,接下来我们来分析一下,来梳理一下我们刚刚用到的东西吧

总结

Spring框架中的工厂

1.ApplicationContext接口
* 使用ApplicationContext工厂的接口,使用该接口可以获取到具体的Bean对象
* 该接口下有两个具体的实现类
    * ClassPathXmlApplicationContext            -- 加载类路径下的Spring配置文件
    * FileSystemXmlApplicationContext           -- 加载本地磁盘下的Spring配置文件
2.BeanFactory工厂(是Spring框架早期的创建Bean对象的工厂接口)

使用BeanFactory接口也可以获取到Bean对象

 public static void main(String[] args) {
        BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        MyService myService  = (MyService) factory.getBean("userService");
        myService.showTest();
    }

BeanFactory和ApplicationContext的区别

BeanFactory--BeanFactory采取延迟加载,第一次getBean时才会初始化Bean

ApplicationContext--在加载applicationContext.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能

  • 事件传递
  • Bean自动装配
  • 各种不同应用层的Context实现

依赖注入(DI)

IOC和DI的概念
  • IOC-- Inverse of Control,控制反转,将对象的创建权反转给Spring!!
  • DI -- Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!
DI(依赖注入)
  • 例如:如果UserServiceImpl的实现类中有一个属性,那么使用Spring框架的IOC功能时,可以通过依赖注入把该属性的值传入进来!!
  • 具体的配置如下:
<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="userService" class="com.zhong.springdemo.MyService">
        <!--给textStr属性注入值-->
        <property name="textStr" value="这是一个测试的语句"/>
    </bean>

</beans>
Spring框架的属性注入详细
  1. 对于类成员变量,常用的注入方式有两种
  • 构造函数注入
  • 属性setter方法注入
  1. 在Spring框架中提供了前两种的属性注入的方式
构造方法的注入方式,两步

1.编写Java的类,提供构造方法

public class Car {
    private String name;
    private double money;
    public Car(String name, double money) {
        this.name = name;
        this.money = money;
    }
    
     @Override
     public String toString() {
     return "Car [name=" + name + ", money="money + "]";
    }
}

2.编写配置文件

<bean id="car" class="com.zhong.Car">
    <constructor-arg name="name" value="大奔"/>
    <constructor-arg name="money" value="100"/>
</bean>
属性的setter方法的注入方式 两步

1.编写Java的类,提供属性和对应的set方法即可

2.编写配置文件
如果Java类的属性是另一个Java的类,那么需要怎么来注入值呢?

<property name="name" rel="具体的Bean的ID或者name的值"/>

例如:

<bean id="person" class="com.zhong.Person">
    <property name="pname" value="美美"/>
    <property name="car2" ref="car2"/>
</bean>
Spring的2.5版本中提供了一种:p名称空间的注入
1. 步骤一:需要先引入 p 名称空间
* 在schema的名称空间中加入该行:xmlns:p="http://www.springframework.org/schema/p"
2. 步骤二:使用p名称空间的语法
* p:属性名 = ""
* p:属性名-ref = ""
3. 步骤三:测试
<bean id="person"class="com.itheima.demo4.Person" p:pname="老王" p:car2-ref="car2"/>
Spring的3.0提供了一种:SpEL注入方式
1. SpEL:Spring Expression Language是Spring的表达式语言,有一些自己的语法
2. 语法
* #{SpEL}
3. 例如如下的代码
<!-- SpEL的方式 -->
<bean id="person"class="com.itheima.demo4.Person>
    <property name="pname"value="#{'小风'}"/>
    <property name="car2" value="#{car2}"/>
</bean>
4. 还支持调用类中的属性或者方法
* 定义类和方法,例如
public class CarInfo {
    public String getCarname(){
        return "奇瑞QQ";
    }
}
数组,集合(List,Set,Map),Properties等的注入
1. 如果是数组或者List集合,注入配置文件的方式是一样的
<bean id="textBean" class="com.zhong.TextBean">
    <property name="arrs">
        <list>
            <value>美美</value>
            <value>小风</value>
        </list>
    </property>
</bean>
2. 如果是Set集合,注入的配置文件方式如下:
<property name="sets">
    <set>
        <value>哈哈</value>
        <value>呵呵</value>
    </set>
</property>
3. 如果是Map集合,注入的配置方式如下:
<property name="map">
    <map>
        <entry key="老王2" value="38"/>
        <entry key="凤姐" value="38"/>
        <entry key="如花" value="29"/>
    </map>
</property>
4. 如果是properties属性文件的方式,注入的配置如下:
<property name="pro">
        <props>
            <prop key="uname">root</prop>
            <prop key="pass">123</prop>
        </props>
    </property>

Spring框架的配置文件分开管理

我们再刚刚的例子当中值加载了一个配置文件,那么我需要加载两个配置文件怎么办呢?例如:在src的目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加载这两个配置文件的方式有两种!

主配置文件中包含其他的配置文件:
<import resource="applicationContext2.xml"/>
工厂创建的时候直接加载多个配置文件:
ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");

结尾

这里我们使用最初始最简单的方法来入门spring 框架,当然再开发中我们是不可能这样写的。这样写一旦文件一多,看起来非常多的配置,而且开发效率也非常低。我们都是使用注解的方式来开发。具体怎么使用呢?我们下片文章再分析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容