美文网首页spring我爱编程
Spring框架-2(IOC上)

Spring框架-2(IOC上)

作者: zhonj | 来源:发表于2017-09-25 17:29 被阅读397次

    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 框架,当然再开发中我们是不可能这样写的。这样写一旦文件一多,看起来非常多的配置,而且开发效率也非常低。我们都是使用注解的方式来开发。具体怎么使用呢?我们下片文章再分析

    相关文章

      网友评论

        本文标题:Spring框架-2(IOC上)

        本文链接:https://www.haomeiwen.com/subject/dnhdextx.html