注意事项

  1. <bean id="helloWorld" class="com.lijunyang.model">
  2. <property name="name" value="Spring"></property>
  3. </bean>

利用类型返回IOC容器中的Bean(setter方法注入的),要求IOC容器中必须只有一个该类型的Bean。

IOC&DI 介绍

IOC 反转资源获取方向

  1. 容器主动的将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接收资源,类似订报纸的感觉,送报纸的工人,将报纸送到你的家里或者手上。举个简单的例子,买菜,原来要你自己到菜场去买,现在通过IOC思想反转资源获取的方向,就是你在网上订菜,然后菜由人专门送到你家里或手上。<br />**IOC的前生---分离接口与实现,需求生产htmlpdf不同类型的报表**<br />**![image.png](https://cdn.nlark.com/yuque/0/2019/png/219938/1559371154536-1b980fd2-8e91-47bb-adb5-837fbd9ad70d.png#align=left&display=inline&height=306&name=image.png&originHeight=306&originWidth=1030&size=218451&status=done&width=1030)**<br />**IOC的前生---采用工厂设计模式**<br />**![image.png](https://cdn.nlark.com/yuque/0/2019/png/219938/1559371233036-b0e4de6d-6a6d-4a0c-a042-72073519f796.png#align=left&display=inline&height=308&name=image.png&originHeight=308&originWidth=757&size=186907&status=done&width=757)**<br />**IOC采用反转控制**<br />**![image.png](https://cdn.nlark.com/yuque/0/2019/png/219938/1559371107370-477b25f0-c396-4ed2-9a03-daa6c4791dda.png#align=left&display=inline&height=403&name=image.png&originHeight=403&originWidth=1048&size=304019&status=done&width=1048)**

DI IOC的另一种表现形式

  1. 组件以一些预先定义好的方式,例如setter方法,接受来自如容器的资源注入,相对IOC而言,这种表述更直接。

配置Bean

  • 配置形式:基于XML文件的方式;基于注解的方式;
  • Bean的配置方式:通过全类名(反射),通过工厂方法(静态工厂方法&实例工厂方法),FactoryBean
  • IOC容器 BeanFactory & ApplicationContext 概述
  • 依赖注入的方式:属性注入;构造器注入
  • 注入属性值细节
  • 自动转配
  • Bean之间的关系:继承;依赖
  • Bean的作用域: singleton;prototype;WEB环境作用域
  • 使用外部属性文件
  • spEL
  • IOC容器中Bean的生命周期
  • Spring4.x新特性:泛型依赖注入

Spring Bean 与IOC&DI 介绍 - 图1

Spring IOC容器

在Spring IOC容器读取Bean配置创建Bean实例之前,必须对它进行实例化,只有在容器实例化后,才可以从IOC容器里获取Bean实例并使用。
Spring提供了两种类型的IOC容器实现,

  1. BeanFactory IOC容器的基本实现
  2. ApplicationContext 提供了更多的高级特性,是BeanFactory的子接口。

BeanFactory是Spring框架的基础设施,面向Spring本身;
applicationContext面向使用Spring框架的开发者,几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory
无论使用何种方式,配置文件是相同的。

ApplicationContext

ApplicationContext的主要实现类:
ClassPathXmlApplicationContext 从类路径下加载配置文件
FileSystemXmlApplicationContext 从文件系统中加载配置文件
ConfigurableApplicationContext 扩展与ApplicationContext,新增加了两个主要方法:refresh()和close(),让ApplicationContext具有启动,刷新,和关闭上下文的能力
ApplicationContext 在初始化上下文时就实例化所有单例的Bean。

WebApplicationContext 是专门为WEB应用而准备的,它允许从相对与WEB根目录的路径中完成初始化工作

依赖注入的方式

Spring支持3中依赖注入的方式

属性注入

属性注入即通过setter方法注入Bean的属性值或依赖的对象
属性注入使用元素,使用name属性制定Bean的属性名称,value属性或子节点指定属性值
属性注入是实际应用中最常用的注入方式

  1. // src/applicationCentext.xml
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="
  7. http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  11. <bean id="helloWorld" class="com.lijunyang.model">
  12. <property name="name" value="Spring"></property>
  13. </bean>
  14. </beans>

构造器注入

通过构造器注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用。
构造器注入在元素里声明属性
中没有name属性
可以通过index和type来区分构造方法

  1. // src/applicationCentext.xml
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5. xmlns:context="http://www.springframework.org/schema/context"
  6. xsi:schemaLocation="
  7. http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  11. <bean id="car2" class="com.lijunyang.model">
  12. <constructor-arg value="Baoma" type="java.lang.String" />
  13. <constructor-arg value="Shanghai" type="java.lang.String" />
  14. <constructor-arg value="240" type="int" />
  15. </bean>
  16. <bean id="car" class="com.lijunyang.model">
  17. <constructor-arg value="Audi" index="0" />
  18. <constructor-arg value="Shanghai" index="1" />
  19. <constructor-arg value="300000" type="double" />
  20. </bean>
  21. </beans>
  22. public class Car {
  23. private String brand;
  24. private String corp;
  25. private double price;
  26. private int maxSpeed;
  27. public Car(String brand, String corp, double price) {
  28. super();
  29. this.brand = brand;
  30. this.corp = corp;
  31. this.price = price;
  32. }
  33. public Car(String brand, String corp, int maxSpeed) {
  34. super();
  35. this.brand = brand;
  36. this.corp = corp;
  37. this.maxSpeed = maxSpeed;
  38. }
  39. }
  40. public class Main {
  41. public static void main(String[] args) {
  42. // 创建 Spring IOC容器
  43. org.springframework.context.ApplicationContext ctx =
  44. new ClassPathXmlApplicationContext("applicationContext.xml");
  45. // 从容器中取出 Bean实例
  46. Car car = (Car) ctx.getBean("car");
  47. System.out.println(car);
  48. Car car2 = (Car) ctx.getBean("car2");
  49. System.out.println(car2);
  50. // brand=Audi corp=Shanghai price=300000
  51. // brand=Baoma corp=Shanghai maxSpeed=240
  52. }
  53. }

工厂方法注入(很少使用,不推荐) 略

Spring 配置的细节

字面量

  1. 字面值:可用字符串表示的值,可以通过<value>元素标签或value属性进行注入。
  2. 基本数据类型及其封装类,String等类型都可以采取字面值注入的方式。
  3. 若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来。
  4. <bean id="car2" class="com.lijunyang.model.Car">
  5. <constructor-arg type="java.lang.String">
  6. <value>Baoma</value>
  7. </constructor-arg>
  8. <constructor-arg type="java.lang.String">
  9. <value><![CDATA[<shanghai^>]]></value>
  10. </constructor-arg>
  11. <constructor-arg type="int">
  12. <value>250</value>
  13. </constructor-arg>
  14. </bean>

引用其他Bean

  • 组成应用程序的Bean经常需要相互协作以完成应用程序的功能,要使Bean能够互相访问,就必须在Bean配置文件中指定对Bean的引用
  • 在Bean的配置文件中,可以通过元素或ref属性为Ben的属性或构造器参数指定对Bean的引用。
  • 也可以在属性或构造器里包含Bean的声明,这样的Bean称之为内部Bean
  1. // src/com/lijunyang/model/Person.java
  2. public class Person {
  3. private String name;
  4. private int age;
  5. private Car car;
  6. // getter/setter toString
  7. }
  8. // src/applicationCentext.xml
  9. <?xml version="1.0" encoding="UTF-8"?>
  10. <beans xmlns="http://www.springframework.org/schema/beans"
  11. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  12. xmlns:context="http://www.springframework.org/schema/context"
  13. xsi:schemaLocation="
  14. http://www.springframework.org/schema/beans
  15. http://www.springframework.org/schema/beans/spring-beans.xsd
  16. http://www.springframework.org/schema/context
  17. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  18. <bean id="car2" class="com.lijunyang.model.Car">
  19. <constructor-arg type="java.lang.String">
  20. <value>Baoma</value>
  21. </constructor-arg>
  22. <constructor-arg type="java.lang.String">
  23. <value><![CDATA[<shanghai^>]]></value>
  24. </constructor-arg>
  25. <constructor-arg type="int">
  26. <value>250</value>
  27. </constructor-arg>
  28. </bean>
  29. <bean id="person" class="com.lijunyang.model.Person">
  30. <property name="name" value="Tom">
  31. <property name="age" value="24">
  32. <property name="car" ref="car2">
  33. /*
  34. <property name="name">
  35. <ref bean="car2" />
  36. </property>
  37. */
  38. /* 内部bean
  39. <bean id="car2" class="com.lijunyang.model.Car">
  40. <constructor-arg type="java.lang.String">
  41. <value>Ford</value>
  42. </constructor-arg>
  43. <constructor-arg type="java.lang.String">
  44. <value><![CDATA[<shanghai^>]]></value>
  45. </constructor-arg>
  46. <constructor-arg type="double">
  47. <value>200000</value>
  48. </constructor-arg>
  49. </bean>
  50. */
  51. </bean>
  52. </beans>

输入参数详解: null值和级联属性

  • 可以使用专门的元素标签为Bean的字符串或其他对象类型的属性注入null值
  • 和Struts,Hiberante等框架一样,Spring支持级联属性的配置 image.png
    1. <bean id="person" class="com.lijunyang.model.Person">
    2. <constructor-arg value="Jerry" type="java.lang.String" />
    3. <constructor-arg value="25">
    4. /* 设置null值
    5. <constructor-arg>
    6. <null/>
    7. </constructor-arg>
    8. */
    9. <constructor-arg ref="car2">
    10. // 设置级联属性。注意:属性需要先初始化后才可以为级联属性赋值,否则会异常,和Struts2不同。
    11. <property name="car.price" value="250000" />
    12. </bean>

集合属性

  • 在Spring中可以通过一组内置的xml标签 来配置集合属性
  • 配置java.util.List类的属性,需要指定list标签,在标签里包含一些元素,这些标签可以通过指定简单的常量值,通过指定对其他Bean的引用,通过指定内置的Bean定义,通过指定空元素,甚至可以内嵌其他集合。
  • 数组的定义和List一样,都使用
  • 配置java.util.Set需要使用set标签,定义元素的方法和List一样
  1. // src/com/lijunyang/model/Person.java
  2. public class Person {
  3. private String name;
  4. private int age;
  5. private List<Car> cars;
  6. // getter/setter toString
  7. }
  8. // src/applicationCentext.xml
  9. <?xml version="1.0" encoding="UTF-8"?>
  10. <beans xmlns="http://www.springframework.org/schema/beans"
  11. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  12. xmlns:context="http://www.springframework.org/schema/context"
  13. xsi:schemaLocation="
  14. http://www.springframework.org/schema/beans
  15. http://www.springframework.org/schema/beans/spring-beans.xsd
  16. http://www.springframework.org/schema/context
  17. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  18. <bean id="person" class="com.lijunyang.model.Person">
  19. <property name="name" value="Tom">
  20. <property name="age" value="24">
  21. <property name="cars">
  22. <list>
  23. <ref bean="car2" />
  24. <bean class="com.lijunyang.model.Car">
  25. <constructor-arg type="java.lang.String">
  26. <value>Baoma</value>
  27. </constructor-arg>
  28. <constructor-arg type="java.lang.String">
  29. <value><![CDATA[<shanghai^>]]></value>
  30. </constructor-arg>
  31. <constructor-arg type="int">
  32. <value>250</value>
  33. </constructor-arg>
  34. </bean>
  35. </list>
  36. </property>
  37. </bean>
  38. </beans>

集合属性

  • java.util.Map 通过标签定义,标签里可以使用多个作为子标签,每个条目包含一个键和一个值
  • 必须在标签里定义键
  • 因为键和值的类型没有限制,所以可以自由地为它们指定,,元素。
  • 可以将Map的键和值作为属性定义:简单常量使用key和value来定义;Bean引用通过key-ref和value-ref属性定义
  • 使用定义java.util.Properties,该标签使用多个作为子标签,每个标签必须定义key属性
  1. public class Person {
  2. private String name;
  3. private int age;
  4. private Map<String, Car> cars;
  5. // getter/setter toString
  6. }
  7. // src/applicationCentext.xml
  8. <?xml version="1.0" encoding="UTF-8"?>
  9. <beans xmlns="http://www.springframework.org/schema/beans"
  10. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  11. xmlns:context="http://www.springframework.org/schema/context"
  12. xsi:schemaLocation="
  13. http://www.springframework.org/schema/beans
  14. http://www.springframework.org/schema/beans/spring-beans.xsd
  15. http://www.springframework.org/schema/context
  16. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  17. <bean id="person" class="com.lijunyang.model.Person">
  18. <property name="name" value="Tom">
  19. <property name="age" value="24">
  20. <property name="cars">
  21. <map>
  22. <entry key="AA" value-ref="car2" />
  23. </map>
  24. </property>
  25. </bean>
  26. </beans>
  1. public class DataSource {
  2. private Properties properties;
  3. public Properties getProperties() {
  4. return properties;
  5. }
  6. public void setProperties(Properties properties) {
  7. this.properties = properties;
  8. }
  9. @Override
  10. public String toString() {
  11. return "DataSource [properties=" + properties + "]";
  12. }
  13. }
  1. <bean id="dataSource"
  2. class="com.lijunyang.model.DataSource">
  3. <property name="properties">
  4. <props>
  5. <prop key="user">root</prop>
  6. <prop key="password">1234</prop>
  7. <prop key="jdbcUrl">jdbc:mysql:\\\test</prop>
  8. <prop key="driverClass">com.mysql.jdbc.Driver</prop>
  9. </props>
  10. </property>
  11. <bean>

使用utility scheme 定义

  • 使用基本的集合标签定义集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同的Bean之间共享集合
  • 可以使用util.schema 里的集合标签定义独立的集合Bean,需要注意的是,必须在根元素里添加 util schema 定义

image.png
image.png

  1. <!-- 配置单例的集合bean,以供多个bean进行引用,需要导入util命名空间 -->
  2. <util:list id="cars">
  3. <ref bean="car2" />
  4. </util:list>

使用p命名空间

image.png
image.png

  1. <!-- 通过p命名空间为bean的属性赋值,需要先导入p命名空间。相对于传统的配置方式更加简洁 -->
  2. <bean id="person5" class="com.lijunyang.model.Person" p:age="30" p:name="Queen"
  3. p:cars-ref="cars" />