Spring IOC概述—依赖注入,集合注入,SPEL,自动装配

一.Spring IOC是什么

1.IOC简述
 Ioc—Inversion of Control,即“控制反转”,是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。简言之,就是使用对象的时候不再“随用随new”,也不用new一个对象然后给它赋值,这些通过IOC容器都能由系统自动生成。

2.Spring IOC优点

  1. 轻量级 2. 依赖注入 3. 面向切面编程 4. 容器 5. 一站式

二.如何使用Spring IOC

  1. 搭建Spring 环境
    1.引入4个所需jar包 spring-beans spring-context spring-core spring expression
    2.配置文件,在target\classes\config目录下创建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
        https://www.springframework.org/schema/beans/spring-beans.xsd">


 </beans>

2.作用域scope
1.singleton (默认属性)
Spring将Bean放入Spring IOC容器的缓存池中,并将Bean引用返回给调用者,spring
IOC继续对这些Bean进行后续的生命管理。BeanFactory只管理一个共享的实例。所有对这个特定 bean的实例请求,都导致返回这个唯一
bean实例的引用。
即每次拿到的对象都是引用的同一个地址的对象。当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。
2.prototype
Spring将Bean返回给调用者,调用者负责Bean后续生命的管理,Spring不再管理这些Bean的生命周期。
每次对这个bean的实例请求都会导致一个新的实例的创建。当用户需要不受其他用户对象影响的对象或有类似的需求时,这是一个较理想的解决办法。
即每次拿到的对象都是引用的不同地址的对象。相当于一个new的操作。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责
3.依赖注入

	3.1.属性注入步骤
		3.1.1.在目标类中声明属性并生成Set方法
		3.1.2.在xml文件中进行配置
 <bean id="apple" class="com.zzxtit.spring.ioc.dev.Apple" scope="prototype" name="weight" value="0.5KG"></bean>  
 <bean id="banana" class="com.zzxtit.spring.ioc.dev.Banana" name="weight" value="0.2KG"></bean> 
		3.1.3在Test类中使用
		注:若属性值为引用类型,则value换成ref,引号的内容换为该引用类型在bean中注入时的id
 public static void main(String[] args) {
    
  Apple apple = (Apple) FruitFactory.getFruit("apple");  
  Orange orange = (Orange) FruitFactory.getFruit("orange");
  System.out.println(orange + "============>" + apple);
 }
	3.2.构造器注入(通过构造方法注入)
	spring 通过构造器注入,两种方式:
	 3.2.1、通过构造方法的参数的顺序,使用属性INDEX, 从0开始。使用方法同3.1.3
 <bean id="constructorDi" class="com.zzxtit.spring.ioc.di.ConstructorDI">
  <constructor-arg index="0" ref="apple">
  </constructor-arg>
  <constructor-arg index="1" value="张三">
  </constructor-arg> 
  <constructor-arg index="2" value="19">
  </constructor-arg>
 </bean> 
  
		3.2.2、通过参数的类型确认使用的构造方法,使用属性ype, 如果基本数数据类型或者String类型,直接写类型名称,如果是自定义或者其他引用类型,需要全类名。使用方法同3.1.3。
 <bean id="constructorDi" class="com.zzxtit.spring.ioc.di.ConstructorDI">
   <constructor-arg type="java.lang.String" alue="realName李学霸">
   </constructor-arg> 
   <constructor-arg type="java.lang.String" value="userName李学霸">
   </constructor-arg>
   <constructor-arg type="com.zzxtit.spring.ioc.di.Apple" ref="apple">
   </constructor-arg>
   <constructor-arg type="int" value="19">
   </constructor-arg> 
  </bean>

4.注入集合(List Map Set properties)

4.1.在xml中将所需集合注入
<bean id="collectionDi"
  class="com.zzxtit.spring.ioc.di.CollectionDI">
  <property name="stuList">
   <list>
    <value>list1</value>
    <value>list2</value>
    <value>list3</value>
   </list>
  </property>
  <property name="major">
   <set>
    <value>major1</value>
    <value>major2</value>
    <value>major3</value>
   </set>
  </property>
  <property name="score" ref="scoreMap">

   <map>
    <entry key="stu1" value="70"></entry>
    <entry key="stu2" value="79"></entry>
    <entry key="stu3" value="76"></entry>
   </map>

  </property>
  <property name="pro">
   <props>
    <prop key="mysql_url">jdbc:mysql://localhost:3306/test</prop>
    <prop key="mysql_driver">com.jdbc.mysql.Driver</prop>
   <props>
    </property>
 </bean>
4.2.在Test类中调用IOC容器创建CollectionDi对象
	注:CollectionDi类重写toString方法便于结果显示,代码如下
@Override
 public String toString() {
  return "CollectionDI [stuList=" + stuList.getClass() + ", majorList=" + majorList.getClass() + ", score=" + score.getClass() + ", pro=" + pro
    + "]";
 }
	测试类中代码如下
public static void main(String[] args) {
  ApplicationContext ioc = new  ClassPathXmlApplicationContext("config/applicationContext-di.xml");
  //参数为applicationContext-di.xml目录
  CollectionDI collectionDi = ioc.getBean("collectionDi", CollectionDI.class);
  System.out.println("============>" + collectionDi);
  //因为重写了toString,所以打印结果是集合的内容
 }

5 util标签,p命名空间,引入外部属性文件
5.1使用 util schema 里的集合标签定义独立的集合 Bean,可以被公用。
注:使用util标签时需引入:
1、命名空间:xmlns:util=“http://www.springframework.org/schema/util”
2、引入xsd文件:http://www.springframework.org/schema/util
https://www.springframework.org/schema/util/spring-util.xsd

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/util
        https://www.springframework.org/schema/util/spring-util.xsd">
</beans>
	声明如下
<util:map id="scoreMap">
  <entry key="张" value="70"></entry>
  <entry key="李" value="79"></entry>
  <entry key="赵" value="76"></entry>
 </util:map>
	使用如下,在properties中用ref引用被声明的bean的id
<bean id="collectionDi"
  class="com.zzxtit.spring.ioc.di.CollectionDI">  
  <property name="score" ref="scoreMap">
  </property>
 </bean>
	5.2 p命名空间
	 Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过 <bean> 元素属性的方式配置 Bean 的属性
	 注:使用p命名空间需要引入命名空间:xmlns:p="http://www.springframework.org/schema/p"
xmlns:p="http://www.springframework.org/schema/p"
	p标签的使用示例
<bean id="apple" class="com.springioc.Apple" p:color="红色" p:type="普通">
 </bean>
 <bean id="studentPtest" class="com.springioc.Student" p:teacher-ref="teacher">
 </bean>
      5.3引入外部属性文件
	Spring 提供了一个 PropertyPlaceholderConfigurer 的 BeanFactory 后置处理器, 这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中. 可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性, 并使用这些属性来替换变量.
	Spring还允许在属性文件中使用${propName},以实现属性之间的相互引用。在Spring2.5之后:可通过<context:property-placeholder>元素,在<beans>中添加context Schema定义。在配置文件中添加如下配置:<context:property-placeholder location="calsspath:db.properties">

	1).创建属性文件:*.properties  文件内容为key=value的键值方式
	eg:在config文件夹下新建一个db.properties文件,内容如下
mysql_url=jdbc:mysql://localhost:3306/test
mysql_driver=com.jdbc.mysql.Driver
	2).在xml文件中用${ }引用该文件内容
<!-- 引入properties 配置文件 -->
 <context:property-placeholder location="config/db.properties"/>
<bean id="collectionDi" class="com.springioc.CollectionDI">
 <property name="pro">
  <props>
   <prop key="mysql_url">${mysql_url}</prop>
   <prop key="mysql_driver">${mysql_driver}</prop>
  </props>
 </property>
</bean>

6.SPEL

    1.SPEL简述
	1.1.Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
	语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL
	1.2.SpEL 为 bean 的属性进行动态赋值提供了便利
	1.3.SpEL作用:
	    1).通过 bean 的 id 对 bean 进行引用
	    2).调用方法以及引用对象中的属性
	    3).计算表达式的值
	    4).正则表达式的匹配
    2.引用 Bean、属性和方法
<bean id="stu" class="com.springioc.Student">
	<property name="ci1" value="#{ci}">/property>
	<property name="ci2" value="#{ci.toString}">/property>
	<property name="ci3" value="#{ci.class}">/property>
</bean>
	注:当value的值是一个方法时,其对应的property标签的name值"ci2"应该为一个属性跟被引用方法( toString() )返回值相同的bean注入的类(Student)中的变量。
7.自动装配
	1).语法
<bean id="..." class=".." autowire="byType"/>
	2).autowire属性取值如下:
		byType:按类型装配,可以根据属性的类型,在容器中寻找跟该类型匹配的bean。如果发现多个,那么将会抛出异常。如果没有找到,即属性值为null。
		byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到,即属性值为null。
		Constructor:与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。	
8.在classpath自动扫描Bean组件(通过加注解的方式)
	1.特定组件包括:
		@Component: 基本注解, 标识了一个受 Spring 管理的组件
		@Repository: 标识持久层组件
		@Service: 标识服务层(业务层)组件
		@Controller: 标识表现层组件
	注:对于扫描到的组件, Spring 有默认的命名策略: 使用非限定类名, 第一个字母小写. 也可以在注解中通过 value 属性值标识组件的名称
	2.@Autowired 注解自动装配具有兼容类型的单个 Bean属性
		2.1.构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Autowired 注解
		2.2默认情况下, 所有使用 @Autowired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Autowired 注解的 required 属性为 false
		2.3默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 以指定注入 Bean 的名称
		2.4@Autowired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.
		2.5@Autowired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean. 
		2.6@Autowired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章