IOC容器
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.xsd">
<bean id="..." class="...">
<!-- 在这里写 bean 的配置和相关引用 -->
</bean>
<bean id="..." class="...">
<!-- 在这里写 bean 的配置和相关引用 -->
</bean>
<!-- 更多bean的定义写在这里 -->
</beans>
2.实例化容器
基础包:
spring-beans :
BeanFactory提供配置结构和基本功能 加载并初始化bean
spring-context
ApplicationContext保存Bean对象并使用
2.1 本地文件
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:/file.txt");
2.2 Classpath
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
2.3 web应用
使用监听器
<listener>
<listener-class>org.springframework.web.context.ContextLoadListener</listener-class>
</listener>
使用Servlet
<servlet>
<servlet-name>contextLoadServlet</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoadServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
3.使用容器
// 创建并配置beans
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
// 取得配置的实例
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// 使用实例
List<String> userList = service.getUsernameList();
Bean概述
属性名 | 说明 |
---|---|
class | “实例化bean” |
name | “bean的命名” |
scope | “Bean作用域” |
constructor arguments | “依赖注入” |
properties | “依赖注入” |
autowiring mode | “自动装配协作者” |
lazy-initialization mode | “延迟初始化bean” |
initialization method | “初始化回调函数” |
destruction method | “析构回调函数” |
1.内部类名.
如果你想配置使用静态的内部类,你必须用内部类的二进制名称。
例如,在com.example包下有个Foo类,这里类里面有个静态的内部类Bar,这种情况下bean定义的class属性
com.example.Foo$Bar
使用$字符来分割外部类和内部类的名称。
使用静态工厂方法实例化
/**
* UserServiceLoader
* Created by heqianqian on 2017/4/24.
*/
public class UserServiceLoader {
private static UserService userService = new UserServiceImpl("haha");
private UserServiceLoader() {
}
public static UserService getInstance() {
return userService;
}
}
<bean id="userFactory" class="ioc.factory.UserServiceLoader" factory-method="getInstance"/>
依赖注入DI
指对象之间的依赖关系
一起协作的其他对象只通过构造器的参数、工厂方法的参数或者由构造函数或者工厂方法创建的对象设置属性。因此容器的工作就是创建bean并注入那些依赖关系。
这个过程实质通过直接使用类的构造函数或者服务定位模式来反转控制bean的实例或者其依赖关系的位置,因此它有另外一个名字叫控制反转 (IoC)。
DI主要有两种注入方式,即构造器注入和Setter注入。
构造器注入
1.参数类型定义不存在潜在的歧义【不同类型的引用类型】
package x.y;
public class Foo {
public Foo(Bar bar, Baz baz) {
// ...
}
}
<beans>
<bean id="foo" class="x.y.Foo">
<constructor-arg ref="bar"/>
<constructor-arg ref="baz"/>
</bean>
<bean id="bar" class="x.y.Bar"/>
<bean id="baz" class="x.y.Baz"/>
</beans>
2. 参数为基本类型或者String类型
2.1 使用type区别
public class Student {
private Integer sNum;
private String sName;
public Student() {
}
public Student(Integer sNum, String sName) {
this.sNum = sNum;
this.sName = sName;
}
@Override
public String toString() {
return "Student{" +
"sNum=" + sNum +
", sName='" + sName + '\'' +
'}';
}
}
<constructor-arg type="java.lang.Integer" value="2014"/>
<constructor-arg type="java.lang.String" value="hqq1"/>
2.2 使用index区别 index从0开始
<constructor-arg index="0" value="2014"/>
<constructor-arg index="1" value="hqq2"/>
2.3 使用构造器参数命名
代码编译时要打开编译模式,这样Spring可以检查构造方法的参数。
如果你不打开调试模式(或者不想打开),也可以使用 @ConstructorProperties JDK注解明确指出构造函数的参数
<constructor-arg name="sNum" value="2014"/>
<constructor-arg name="sName" value="hqq3"/>
Setter注入
public class User {
private String name;
private int age;
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
<bean id="user" class="ioc.entity.User">
<property name="name" value="heqianqian"/>
<property name="age" value="22"/>
</bean>
注入Properties
方法一:
<property name="properties">
<value>
name=MR.LI
class=1405
</value>
</property>
方法二:
<property name="properties">
<props>
<prop key="name">MR.Huang</prop>
<prop key="class">1405</prop>
</props>
</property>
注入List
<property name="clazzs">
<list>
<value>1405</value>
<value>1406</value>
<value>1407</value>
<value>1408</value>
</list>
</property>
注入Map
<property name="courseName">
<map>
<entry key="1405" value="JAVA程序设计"/>
<entry key="1406" value="C程序设计"/>
<entry key="1407" value="C++程序设计"/>
<entry key="1408" value="C#程序设计"/>
</map>
</property>
注入Set
<property name="classRooms">
<set>
<value>5-206</value>
<value>5-206</value>
<value>5-206</value>
<value>5-207</value>
</set>
</property>
Bean作用域
singleton:
(默认的) 每个 String IoC 容器作用域中一个 bean 定义只对应一个对象实例。
prototype:
一个 bean 定义对应多个对象实例
request
一个 bean 定义作用于 HTTP request 生命周期;是指每个 HTTP request 拥有自己的通过一个 bean 定义创建的实例。仅在基于 web 的 Spring ApplicationContext 中有效。
session
一个 bean 定义作用于 HTTP session 生命周期。仅在基于 web 的 Spring ApplicationContext 中有效。
global session
一个 bean 定义作用于全局的 HTTP session 生命周期。仅在 portlet context 中使用才有效。仅在基于 web 的 Spring ApplicationContext 中有效。
application
一个 bean 定义作用于整个 ServletContext 生命周期。仅在基于 web 的 Spring ApplicationContext 中有效。
定制bean特性
生命周期回调
1.初始化回调函数
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {
public void init() {
// do some initialization work
}
}
2.析构回调函数
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {
public void cleanup() {
// do some destruction work (like releasing pooled connections)
}
}