【学习笔记-SSH框架】Spring入门-笔记02-IoC容器

Spring入门-笔记02-IoC容器

目录

  1. IoC概述
  2. Bean的生命周期
  3. 配置IoC

1. IoC概述

Spring框架的核心功能是控制反转(IoC),面向切面编程AOP和声明式事务管理等功能都依赖于IoC。

IoC,即通过容器来控制业务对象之间的依赖关系,而非传统实现中的通过代码直接操控,即控制权由应用代码转移到了外部容器,控制权的转移就是反转。

图 Spring IoC容器

为实现IoC功能,Spring提供了两个访问接口

  • BeanFactory:

    BeanFactory是Spring IoC容器的核心接口,是制造Bean的工厂,用于向使用者提供Bean的实例。其主要功能是完成容器管理对象的实例化,并根据预定的配置完成对象之间依赖关系的组装,最终向使用者提供已装配的可用对象。

    图 BeanFactory接口的方法说明

  • ApplicationContext:

    ApplicationContext是BeanFactory的子接口,代表一个应用的上下文,在BeanFactory的基础知识,提供了更多的实用功能。如Bean的生命周期管理,框架事件体系,国际化支持等功能。

BeanFactory初始化 和 ApplicationContext初始化的区别

  • BeanFactory初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例化目标Bean。

  • ApplicationContext初始化上下文时,实例化所有单实例Bean。

2. Bean的生命周期

图 Bean的生命周期

3. 配置IoC

有XML文件和java注解两种方式来配置IoC。

XML文件方式
  1. 在resources文件夹中创建applicationContext.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-2.0.xsd">



</beans>
  1. 创建pojo类,在配置文件中添加bean元素

User.java

package com.chapter08.bean;

public class User {
    private int id;
    private String username;
    private String password;

    public User() {
    }

    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

applicationContext.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-2.0.xsd">

    <bean class="com.chapter08.bean.User" id="user">

    </bean>

</beans>
  • id:id属性确定该Bean的唯一标识符,容器对bean的管理和访问以及该bean的依赖关系,都通过该属性完成。在java代码中通过getBean(“名称”)的方法即可获取相应的Bean。
  • class:class属性指定该Bean的具体实现类,
  • property标签:为属性赋值,其中id对应javaBean的属性,value为要赋予的值
配置依赖注入

依赖注入和控制反转是同一个概念,都是为了处理对象间的依赖关系。

两种注入方式:

  1. setter方法注入
<?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-2.0.xsd">

    <!-- ======================= 依赖注入 ====================== -->
    <!--setter方式注入-->
    <bean class="com.chapter08.bean.User" id="user">
    <property name="id" value="1"/>
    <property name="username" value="AlanLee"/>
    <property name="password" value="123456"/>
    </bean>
    
</beans>
  1. 构造方法注入
<?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-2.0.xsd">

    <!-- ======================= 依赖注入 ====================== -->
    <!--构造方法方式注入-->
    <bean class="com.chapter08.bean.User" id="user2">
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="username" value="AlanLee"/>
    <constructor-arg name="password" value="123456"/>
    </bean>
    
</beans>

两种注入方式的对比

  • setter方法注入比较直观,自然,易懂
  • 构造方法注入可以决定注入的顺序,但注入复杂的关系时显得臃肿,难以阅读。
注入值类型

有三种注入值类型:字面值,其他Bean的引用,集合类型。

Order.java

public class Order {
    private int id;
    private String orderNo;
    private double amount;

    //测试其他Bean的引用
    private OrderItem orderItem;
    
    //省略setter/getter方法    
}

OrderItem.java

package com.chapter08.bean;

public class OrderItem {
    private int id;
    private String product;
    private float price;
    private int count;
    
    //省略setter/getter方法   
         
}
  1. 字面值类型

字面值一般是指可用字符串表示的值,默认情况下,基本数据类型及其封装类、String等类型都可以采取字面值方式注入。

<!-- 字面值方式 -->
    <bean class="com.chapter08.bean.Order" id="order">
        <constructor-arg name="id" value="100"/>
        <constructor-arg name="orderNo" value="ABCDEF"/>
        <constructor-arg name="amount" value="222.33"/>

    </bean>
  1. 其他Bean的引用

如果Bean需要注入的属性是对象类型,则可以通过<ref>元素或者ref属性注入

    <!-- 字面值方式 -->
    <bean class="com.chapter08.bean.Order" id="order">
        <constructor-arg name="id" value="100"/>
        <constructor-arg name="orderNo" value="ABCDEF"/>
        <constructor-arg name="amount" value="222.33"/>
    
        <!--其他Bean的引用-->
        <property name="orderItem" ref="orderItem"/>

    </bean>

    <!--测试 其他Bean的引用 在Order中引用这个bean-->
    <bean class="com.chapter08.bean.OrderItem" id="orderItem">
        <property name="id" value="1"/>
        <property name="product" value="电视机"/>
        <property name="price" value="6000"/>
        <property name="count" value="1"/>
    </bean>

  1. 集合类型

使用<array>,<list>,<set>,<map><props>元素分别设置类型为数组、List、Set、Map和Properties的集合属性。

Order2.java

public class Order2 {
    private int id;
    private String orderNo;
    private double amount;

    //测试其他Bean的引用
    private OrderItem orderItem;

    //测试集合类型注入
    private Object[] myArray;
    private List<?> myList;
    private Set<?> mySet;
    private Map<?,?> myMap;
    private Properties myProp;
        
    //省略setter/getter方法   
         
}
<!--测试集合类型注入-->
    <bean class="com.chapter08.bean.Order2" id="order2">
      <constructor-arg name="id" value="100"/>
      <constructor-arg name="orderNo" value="ABCDEF"/>
      <constructor-arg name="amount" value="222.33"/>
      <!--其他Bean的引用-->
    <!--      <property name="orderItem" ref="orderItem"/>-->

      <!--测试集合类型注入-->
      <property name="myArray">
          <array>
              <value>1234</value>
              <ref bean="orderItem"/>
          </array>
      </property>

      <property name="myList">
          <list>
              <value>1234</value>
              <ref bean="orderItem"/>
          </list>
      </property>

      <property name="mySet">
          <set>
              <value>1234</value>
              <ref bean="orderItem"/>
          </set>
      </property>

      <property name="myMap">
          <map>
              <entry key="1" value="1234"/>
              <entry key="2" value-ref="orderItem"/>
          </map>
      </property>

      <property name="myProp">
          <props>
              <prop key="aaa">AAA</prop>
              <prop key="bbb">BBB</prop>
          </props>
      </property>
    </bean>
Bean之间的关系
  1. 继承

添加parent属性

<bean id="user2" parent="user"/>

这里的继承不是java中类的继承,而是继承有相同属性的bean

  1. 依赖

添加depend-on属性

<bean id="userDao" class="xxx.xxx.UserDao"/>
<bean id="userService" class="xxx.xxx.UserService" depend-on="userDao"/> 

构造userService时,需要先构造userDao。

Bean的作用域

Bean的作用域通过scope属性完成

Spring支持5中Bean的作用域

图 Bean的作用域

介绍常用的作用域:

  1. singleton

singleton作用域用于提供单实例的Bean对象,只创建一个该Bean对象的实例,这个唯一实例会被缓存起来,当有请求使用时,直接返回该实例,不会创建新的实例。

<!--singleton作用域-->
    <bean class="com.chapter08.bean.Order" id="order" scope="singleton">

Bean的默认作用域就是singleton

  1. prototype

prototype作用域用于向请求者每次请求提供新实例。

<!--prototype作用域-->
    <bean class="com.chapter08.bean.Order" id="order" scope="prototype">

由于频繁的创建和销毁实例会带来很大的开销,所以尽量不使用prototype作用域。

自动装配

自动装配就是我们在不使用和注入数据的情况下,Spring容器自动装配相互协作的bean 的关系
这种方式可以有效减少配置文件的体积

<bean class="com.chapter08.bean.Order" id="order" autowire="装配方式">

有5种自动装配方式:

  1. no:不使用自动装配
  2. byName:当我们这么设置时,Spring 容器会扫描xml配置文件,根据java bean中那个引用类型的参数名称类查找xml配置中是否有符合的名字相同bean配置,找到就注入到该参数;
  3. byType:从Spring环境中获取目标对象时,目标对象中的属性会根据类型在整个spring环境中查找标签的class属性值。如果有相同的,那么获取这个对象,实现关联。
  4. constructor:根据javaBean的构造函数去匹配xml中的一个bean,尝试去寻找匹配项;也不受名称限制
  5. autodetect:通过Bean类的自省机制来决定使用constructor还是byType方式进行自动装配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值