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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。