QuickStart
IoC容器实现步骤:
- 在 pom.xml 中添加 Spring 依赖
- 创建配置文件,可以自定义文件名 spring.xml
- 在 spring.xml 中配置 bean 标签,IoC 容器通过加载 bean 标签来创建对象
- 调用 API 获取 IoC 创建的对象
- 无参构造
<!-- 配置 student 对象 -->
<bean id="stu" class="com.southwind.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="23"></property>
</bean>
<!-- 配置 student 对象 (包含特殊字符)-->
<bean id="stu" class="com.southwind.entity.Student">
<property name="id" value="1"></property>
<property name="name">
<value><![CDATA[<张三>]]></value>
</property>
<property name="age" value="23"></property>
</bean>
Spring 通过调用每个属性的 setter 方法来完成属性的赋值,因此实体类必须有 setter 方法
//1.加载 spring.xml 配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
//2.通过 id 值获取对象
Student stu = (Student) applicationContext.getBean("stu");
//Student stu = applicationContext.getBean(Student.class);
System.out.println(stu);
- 有参构造
<!-- 通过有参构造函数创建对象 -->
<bean id="stu3" class="com.hzit.entity.Student">
<constructor-arg name="id" value="3"></constructor-arg>
<constructor-arg name="name" value="小明"></constructor-arg>
<constructor-arg name="age" value="22"></constructor-arg>
</bean>
<!-- 通过有参构造函数创建对象 -->
<bean id="stu3" class="com.hzit.entity.Student">
<constructor-arg index="0" value="3"></constructor-arg>
<constructor-arg index="1" value="小明"></constructor-arg>
<constructor-arg index="2" value="22"></constructor-arg>
</bean>
- 对象之间有级联关系
public class Classes {
private int id;
private String name;
}
public class Student {
private int id;
private String name;
private int age;
private Classes classes;
}
<!-- 创建 classes 对象 -->
<bean id="classes" class="com.hzit.entity.Classes">
<property name="id" value="1"></property>
<property name="name" value="Java班"></property>
</bean>
<!-- 创建 stu 对象 -->
<bean id="stu" class="com.hzit.entity.Student">
<property name="id" value="1"></property>
<property name="name">
<value><![CDATA[<张三>]]></value>
</property>
<property name="age" value="23"></property>
<!-- 将 classes 对象赋给 stu 对象 -->
<property name="classes" ref="classes"></property>
</bean>
- 集合属性的依赖注入
public class Classes {
private int id;
private String name;
private List<Student> students;
}
<!-- 配置 classes 对象 -->
<bean id="classes" class="com.hzit.entity.Classes">
<property name="id" value="1"></property>
<property name="name" value="Java班"></property>
<property name="students">
<!-- 注入 student 对象 -->
<list>
<ref bean="stu"/>
<ref bean="stu2"/>
</list>
</property>
</bean>
bean的scope
- singleton,单例,表示通过 Spring 容器获取的该对象是唯一的;
- prototype,原型,表示通过 Spring 容器获取的对象都是不同的;
- request,请求,表示在一次 HTTP 请求内有效;
- session,会话,表示在一个用户会话内有效。
Spring 的继承
Spring 的继承是在对象层面进行操作的,即两个 bean 来自同一个类,因此方法是一样的,不存在继承关系
<bean id="user" class="com.southwind.entity.User">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="23"></property>
</bean>
<bean id="user2" class="com.southwind.entity.User" parent="user">
<!-- 覆盖 name 属性 -->
<property name="name" value="李四"></property>
</bean>
User user2 = (User) applicationContext.getBean("user2");
System.out.println(user2);
创建了两个 User 对象 user1 和 user2,并且 user2 继承了 user1 的所有属性。user2 在继承 user1 所有属性的基础之上,还可以对属性进行覆盖
Spring 的依赖
配置依赖关系后,被依赖的 bean 一定先创建,再创建依赖的 bean
<bean id="user" class="com.southwind.entity.User" depends-on="car">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="23"></property>
</bean>
<bean id="car" class="com.southwind.entity.Car">
<property name="id" value="1"></property>
<property name="brand" value="宝马"></property>
</bean>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
User user = (User) applicationContext.getBean("user");
Car car = (Car) applicationContext.getBean("car");
目前为止发现的bean构造顺序:1. singleton bean(根据xml中顺序,遇到deponds-on项先创建 2.prototype bean(根据java中顺序)
Spring 读取外部资源
# resources/jdbc.properties
driverName = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/myTest?useUnicode=true&characterEncoding=UTF-8
user = root
pwd = root
<!--xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context"-->
<!-- 导入外部的资源文件 -->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 创建 C3P0 数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"></property>
<property name="password" value="${pwd}"></property>
<property name="driverClass" value="${driverName}"></property>
<property name="jdbcUrl" value="${url}"></property>
</bean>
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
DataSource ds = (DataSource) applicationContext.getBean("dataSource");
Connection conn = null;
try {
conn = ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(conn);
p 命名空间
<!--xmlns:p="http://www.springframework.org/schema/p-->
<bean id="user" class="com.southwind.entity.User" p:id="1" p:name="张三" p:age="23" p:car-ref="car"></bean>
<bean id="car" class="com.southwind.entity.Car" p:id="1" p:brand="宝马"></bean>
IoC 通过工厂方法创建对象
静态工厂方法
public class StaticCarFactory {
private static Map<Integer,Car> cars;
static{
cars = new HashMap<Integer,Car>();
cars.put(1, new Car(1,"奥迪"));
cars.put(2, new Car(2,"奥拓"));
}
public static Car getCar(int num){
return cars.get(id);
}
}
<!-- 配置静态工厂创建 car 对象 -->
<bean id="car1" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
<constructor-arg value="1"></constructor-arg>
</bean>
实例工厂方法
public class InstanceCarFactory {
private Map<Integer,Car> cars;
public InstanceCarFactory() {
cars = new HashMap<Integer,Car>();
cars.put(1, new Car(1,"奥迪"));
cars.put(2, new Car(2,"奥拓"));
}
public Car getCar(int num){
return cars.get(num);
}
}
<!-- 配置实例工厂对象 -->
<bean id="carFactory" class="com.southwind.entity.InstanceCarFactory"></bean>
<!-- 通过实例工厂对象创建 car 对象 -->
<bean id="car2" factory-bean="carFactory" factory-method="getCar">
<constructor-arg value="2"></constructor-arg>
</bean>
IoC 自动装载(autowire)
byName,通过属性名自动装载;
<bean id="person" class="com.southwind.entity.Person" autowire="byName">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
<constructor-arg value="2"></constructor-arg>
</bean>
<!--创建 person 对象时,没有在 property 中配置 car 属性,因此 IoC 容器会自动进行装载,autowire="byName" 表示通过匹配属性名的方式去装载对应的 bean,Person 实体类中有 car 属性,因此就将 id="car" 的 bean 注入到 person 中。-->
byType,通过属性对应的数据类型自动装载
<bean id="person" class="com.southwind.entity.Person" autowire="byType">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
</bean>
<bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
<constructor-arg value="1"></constructor-arg>
</bean>
基于注解的开发
IoC 中可以给类添加的注解
- @Controller
- @Autowired
- @Service
- @Repository