3.Spring基于XML的IOC细节

Spring基于XML的IOC细节

一、Spring中的工厂的类结构图


spring中工厂的类结构图.png

spring中工厂的类结构图关系.png

1. BeanFactory和ApplicationContext的区别

  1. BeanFactory 是Spring容器的顶层接口。适用于多例模式
    • 需要使用时创建对象
  2. ApplicationContextBeanFactory的子接口,适用于单利模式【常用】
    • 只要一读取配置文件,默认情况下就会创建对象。

2. ApplicationContext接口的实现类

  1. ClassPathXmlApplicationContext

    • 【推荐!】从根路径下加载配置文件
  2. FileSystemXmlApplicationContext

    • 【忘记吧!】从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
  3. AnnotationConfigApplicationContext

    • 当使用注解配置容器对象时,需要使用此类来创建spring容器。它用来读取注解。

二、IOC中bean标签和管理对象细节

bean.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 标签:用于配置让spring 创建对象,并且存入ioc容器中
     id 属性:对象的唯一标识
     class 属性:指定要闯将对象的全限定类名
     -->
    <!-- 配置service -->
    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl" ></bean>
</beans>

如果有多个配置文件,可以在主配置文件中使用<import>标签导入

    ...
    <import resource="classpath*:applicationContext1.xml"></import>
</beans>

1. bean标签的作用

  1. 用于配置对象让spring来创建。
  2. 【默认情况下】调用的是类中的无参构造函数【反射】。如果没有无参构造函数则不能创建成功。

2. bean标签的属性介绍

<bean
    id="accountDao"
    -- 给对象在容器中提供一个唯一标识。用于获取对象。

    class="com.itheima.dao.impl.AccountDaoImpl"
    -- 指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数

    scope="prototype"
    -- 指定对象的作用范围:取值及其含义如下
        -- singleton: 默认值,单例的【常用】
        -- prototype: 多例的
        -- request: web项目中,Spring创建一个Bean对象,将对象存入request域中,请求范围
        -- session: web项目中,Spring创建一个Bean对象,将对象存入session域中,会话范围
        -- golbal-session: web项目中,【应用在Protlet环境,集群环境】,如果没有Protlet
                 环境,那么golbalSession相当于session

    init-method="init"
    -- 指定类中的初始化方法的名称

    lazy-init="true"
    -- 延迟加载,默认false

    destroy-method="destory"
    -- 指定类中销毁方法的名称

></bean>

3. bean的作用范围和生命周期

1. 单例对象:属性scope="singleton"

一个应用只有一个对象的实例。作用范围就是整个引用

  • 生命周期
    • 对象出生:当应用加载,创建容器时,对象就被创建了。
    • 对象活着:容器在,对象在
    • 对象拜拜:应用卸载、容器销毁时。

2. 多例对象:属性scope="prototype"

每次访问对象时,都会重新创建对象实例;销毁方法就不会被执行了!控制权交给GC了

  • 生命周期
    • 对象出生:当使用对象时
    • 对象活着:对象在被使用中
    • 对象拜拜:长时间不使用,被java的垃圾回收机制GC回收了

3. 实例化Bean的三种方式

1. 使用默认无参构造函数

在默认情况下:会根据默认无参构造函数来创建类对象,如果没有默认无参构造函数,将会创建失败。

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>
2. spring管理【静态】工厂-使用静态工厂的方式创建对象【使用jar包中的类】

比如,如下:使用StaticFactory类中静态方法createAccountService创建对象,并存入spring容器

  1. 模拟一个静态工厂类,创建业务层实现类
public class StaticFactory {
    public static AccountService createAccountService() {
        return new AccountServiceImpl();
    }
}
  1. 配置文件bean.xml
<bean
    id="accountService"
    -- 指定bean的id,用于从容器中获取

    class="com.itheima.factory.StaticFactory"
    -- 指定【静态工厂】的全限定类名

    factory-method="createAccountService"
    -- 指定生产对象的静态方法

></bean>
3. spring管理【实例】工厂-使用实力工厂的方法创建对象【使用jar包中的类】

先把工厂的创建交给spring来管理,然后再使用工厂的bean来调用里面的方法;
演示:模拟一个实例工厂,创建业务层实现类,此工厂创建对象,必须现让spring创建该工厂的实例对象,再调用方法

  1. 实例工厂类
public class InstanceFactory {
    public AccountService createAccountService() {
        return new AccountServiceImpl();
    }
}
  1. bean.xml配置
<bean id="instancFactory" class="com.itheima.factory.InstanceFactory"></bean>
-- 实例工厂的bean配置

<bean id="accountService"
    factory-bean="instancFactory"
    -- 指定实例工厂bean的id

    factory-method="createAccountService"
    -- 指定实例工厂中创建对象的方法

></bean>

三、Spring的依赖注入

依赖注入:Dependency Injection,spring框架核心ioc的具体实现。程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

1. 构造函数注入

顾名思义,就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做,而是通过配置的方式,让spring框架来为我们注入。

  1. 被注入的类案例:【类中需要提供一个对应参数列表的构造函数】
public class AccountServiceImpl implements AccountService {

    private String name;
    private Integer age;
    private Date birthday;

    public AccountServiceImpl(String name, Integer age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }
    ...
  1. bean.xml对应的配置的标签constructor-arg介绍
<bean id="xxx" class="xxx.xxx.xxx">
  <constructor-arg
    index="1"
    -- (一般不用)指定参数在构造函数参数列表的索引位置

    type="Integer"
    -- (一般不用)指定参数在构造函数中的数据类型

    name="name"
    -- 【常用】指定参数在构造函数中的名称,形参名称

    -\-\ 上面三个是找给谁赋值,下面两个是赋什么值 /-/-

    value="张三"
    -- 它能赋的值是基本的 数据类型 和String类型

    ref="now"
    -- 能赋的值为其他的bean类型 id,在配置文件中得配置该bean标签,  
     如下
  ></constructor-arg>
</bean>
<bean id="now" class="java.util.Date"></bean>
  1. bean.xml配置案例
<bean id="now" class="java.util.Date"></bean>

<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <constructor-arg name="name" value=" 张三 "></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
    <constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>

2. set方法注入【开发中的常客】

需要在类中提供set方法

  1. bean类文件案例
public class AccountServiceImpl implements IAccountService {
    private String name;
    private Integer age;
    private Date birthday;

    public void setName(String name) { this.name = name; }

    public void setAge(Integer age) { this.age = age; }

    public void setBirthday(Date birthday) { this.birthday = birthday; }

    ...
  1. 涉及的标签property
<property
    name="name"
    -- 被注入类的对应set方法“set”之后的部分首字母小写!

    value="test"
    -- 给属性赋值为基本数据类型和string类型的

    ref="now"
    -- 给属性赋值是其他bean类型的

></property>
<bean id="now" class="java.util.Date"></bean>
  1. bean.xml配置案例
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl">
    <property name="name" value="test"></property>
    <property name="age" value="21"></property>
    <property name="birthday" ref="now"></property>
</bean>
<bean id="now" class="java.util.Date"></bean>

3. 使用p名称空间注入数据(本质还是调用set方法)【了解】

此种方式通过xml中导入p名称空间,使用p:propertyName来注入数据,本质还是调用set方法实现注入功能

  1. java代码【->2. set方法注入【开发中的常客】->1. bean类文件案例】

  2. 配置文件案例

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p"
    -- 引入此命名空间约束

    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="accountService"
    class="com.itheima.service.impl.AccountServiceImpl4"
    p:name="test" p:age="21" p:birthday-ref="now"/>
    -- p:propertyName的形式

</beans>

4. 注入集合属性

给类中的集合成员传值,用的也是注入的方式,只不过变量的数据类型都是集合。一般注入的集合类型为List、Set、Map、Properties

  1. 被注入的JavaBean
public class AccountServiceImpl implements AccountService {

    private String[] myStrs;
    private List<Object> myList;
    private Set<Object> mySet;
    private Map<String, Object> myMap;
    private Properties myProps;

    public String[] getMyStrs() { return myStrs; }

    public void setMyStrs(String[] myStrs) { this.myStrs = myStrs; }

    @Override
    public List<Object> getMyList() { return myList; }

    public void setMyList(List<Object> myList) { this.myList = myList; }

    public Set<Object> getMySet() { return mySet; }

    public void setMySet(Set<Object> mySet) { this.mySet = mySet; }

    public Map<String, Object> getMyMap() { return myMap; }

    public void setMyMap(Map<String, Object> myMap) { this.myMap = myMap; }

    public Properties getMyProps() { return myProps; }

    public void setMyProps(Properties myProps) { this.myProps = myProps; }

    ...
  1. bean.xml中对应的配置
    • 注入集合数据时,只要结构相同,标签可以互换
    • 注入集合时,根据类型选择标签,同种集合类型通用
      • List结构:
        • <array></array>
        • <list></list>
        • <set></set>
      • Map结构的
        • <map></map>
        • <entry></entry>
        • <prop></prop>
        • <props></props>
    <bean id="accountDao" class="com.itheima.dao.impl.AccountDaoImpl" ></bean>

    <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" lazy-init="true">
        <!-- 给数组注入数据 -->
        <property name="myStrs">
            <set>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
            </set>
        </property>

        <!-- 注入list集合数据 -->
        <property name="myList">
            <list>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
                <ref bean="accountDao"></ref>
            </list>
        </property>

        <!-- 注入set集合数据 -->
        <property name="mySet">
            <set>
                <value>AAA</value>
                <value>BBB</value>
                <value>CCC</value>
                <ref bean="accountDao"></ref>
            </set>
        </property>

        <!-- 注入Map数据 -->
        <property name="myMap">
            <props>
                <prop key="A">AAA</prop>
                <prop key="B">BBB</prop>
            </props>
        </property>

        <!-- 注入properties数据 -->
        <property name="myProps">
            <map>
                <entry key="A" value="AAA"></entry>
                <entry key="D" value-ref="accountDao"></entry>
                <entry key="B">
                    <value>BBB</value>
                </entry>
                <entry key="C">
                    <ref bean="accountDao"></ref>
                </entry>
            </map>
        </property>
    </bean>
</beans>

四、Spring配置文件中提示的配置【Eclipse】


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