一.概念理解
1.容器
IoC容器负责容纳并管理bean,在Spring中,BeanFactory
是IoC容器的核心接口。 它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring提供两种IoC容器的实现:
(1)BeanFactory :org.springframework.beans.factory.BeanFactory 是Spring IoC容器的基本实现,是Spring IoC容器实际代表者
BeanFactory是Spring框架的基础设施,面向Spring本身
(2)ApplicationContext:提供了更多的高级特性,是BeanFactory的子类。
ApplicationContext面向开发者。几乎所有的场合都直接使用ApplicationContext而非底层的BeanFactory。
ApplicationContext 的主要实现类:
ClassPathXmlApplicationContext:从 类路径下加载配置文件
FileSystemXmlApplicationContext: 从文件系统中加载配置文件
ConfigurableApplicationContext 扩展于 ApplicationContext,新增加两个主要方法:refresh() 和 close(), 让 ApplicationContext 具有启动、刷新和关闭上下文的能力
2.bean
在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean。 简单地讲,bean就是由Spring容器初始化、装配及管理的对象
bean的定义由BeanDefinition
对象来表示,该定义将包含以下信息:
- 全限定类名: 这通常就是已定义bean的实际实现类。
- bean行为的定义: 这些定义将决定bean在容器中的行为(作用域、生命周期回调等等)
- 对其他bean的引用: 这些引用bean也可以称之为协作bean(collaborators) 或依赖bean(dependencies).
- 创建bean实例时的其他配置设置。比如使用bean来定义连接池,可以通过属性或者构 造参数指定连接数,以及连接池大小限制等。
上述内容直接被翻译为每个bean定义包含的一组properties。
二.bean的配置
1. 简单实例
java bean: HelloWorld.java
package com.ray.spring; public class HelloWorld { private String name; public void setName(String name){ this.name=name; } public void hello(){ System.out.println("hello:"+name); } }
配置文件: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" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 配置一个 bean class:bean的全类名,通过反射的方式在IoC容器中穿件Bean.所以要求Bean中必须有无参构造器 id:标识容器中的bean,id唯一。若有多个id,则第一个是标识符,其他为别名。 --> <bean id="helloWorld" class="com.ray.spring.HelloWorld"> <!-- 为属性赋值 通过属性注入: 通过 setter 方法注入属性值 --> <property name="name" value="Tom"></property> </bean> </beans>
bean的实例化:Main.java
package com.ray.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { //1. 创建 Spring 的 IOC 容器,ApplicationContext代表IoC容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); /*2. 从 IOC 容器中获取 bean 的实例 2.1利用id定位到IoC容器中的bean */ HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld"); //2.2利用类型返回IoC容器中的bean,但要求IoC容器中必须只有一个该类型的bean //HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld"); //3. 使用 bean helloWorld.hello(); } }
2. bean的依赖注入
Spring 支持 3 种依赖注入的方式:属性注入、构造器注入、工厂方法注入(很少使用,不推荐)
2.1 属性注入
属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象
属性注入是实际应用中最常用的注入方式。
<?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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <bean id="helloWorld" class="com.ray.spring.HelloWorld"> <!-- 通过属性注入: 通过 setter 方法注入属性值 <property>节点:设置属性 name :指定 Bean 的属性名称 value 或 <value> 子节点:指定属性值 --> <property name="name" value="Tom"></property> </bean> </beans>
2.2 构造器注入
构造器注入即 通过配置构造器参数,来注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用。
Java bean: Car.java
package com.ray.spring; public class Car { private String brand; private String corp; private double price; private int maxSpeed; public Car(String brand, String corp, double price) { super(); this.brand = brand; this.corp = corp; this.price = price; } public Car(String brand, String corp, int maxSpeed) { super(); this.brand = brand; this.corp = corp; this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxSpeed=" + maxSpeed + "]"; } }
配置文件: 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" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 通过构造器注入属性值 1.按参数顺序注入--> <bean id="car1" class="com.ray.spring.Car"> <!-- 都要求: 在 Bean 中必须有对应的构造器. --> <constructor-arg value="Audi"></constructor-arg> <constructor-arg value="ShangHai"></constructor-arg> <constructor-arg value="300000"></constructor-arg> </bean> <!--2.通过参数索引注入--> <bean id="car2" class="com.ray.spring.Car"> <constructor-arg value="Audi" index="0"></constructor-arg> <constructor-arg value="ShangHai" index="1"></constructor-arg> <constructor-arg value="300000" type="double"></constructor-arg> </bean> <!--3.通过参数类型注入--> <bean id="car3" class="com.ray.spring.Car"> <constructor-arg value="Audi" type="java.lang.String"></constructor-arg> <constructor-arg value="ShangHai" type="java.lang.String"></constructor-arg> <constructor-arg value="300000" type="int"></constructor-arg> </bean> </beans>
bean的实例化:
package com.ray.spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { //1. 创建 Spring 的 IOC 容器,ApplicationContext代表IoC容器 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2. 从 IOC 容器中获取 bean 的实例 Car car=(Car)ctx.getBean("car1"); System.out.println(car); car=(Car)ctx.getBean("car2"); System.out.println(car); car=(Car)ctx.getBean("car3"); System.out.println(car); } }