前言
SpringFramework学习笔记
核心概念
- IoC(Inversion of Control)控制反转
- 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
- Spring技术对IoC思想进行了实现
- Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的外部
- IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中称为Bean
- DI(Dependency Injection)注入
- 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
引入依赖
pox.xml1 2 3 4 5
| <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency>
|
准备工作
src/main/java/com/dao/UserDao.java1 2 3 4 5 6 7 8 9
| package com.dao;
public class UserDao {
public void method() { System.out.println("userDao.method()"); }
}
|
src/main/java/com/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import com.dao.UserDao;
public class UserService {
UserDao userDao = new UserDao();
public void method() { userDao.method(); } }
|
IoC容器快速入门
配置bean
- 创建
applicationContext.xml
配置文件并配置bean
<bean id="" class="" />
、<bean id="" class=""></bean>
:一个bean标签表示一个配置
id=""
:自定义bean的名称,必须唯一不重复,通常首字母小写
class=""
:指定交给Spring管理的Java类,填写类的全局限定名
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8
| <?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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"></bean>
</beans>
|
创建IoC容器并获取bean对象
- 在程序的入口创建IoC容器对象,传递配置文件名
- 通过bean的id获取由Spring管理的bean对象,得到Object类型的对象,可以强制类型转换
getBean("")
:指定bean的id
src/main/java/com/Application1 2 3 4 5 6 7 8 9
| public class Application { public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService obj = (UserService) applicationContext.getBean("userService"); obj.method(); } }
|
DI依赖注入快速入门
通过setter注入
引用类型注入
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import com.dao.UserDao;
public class UserService { UserDao userDao;
public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void method() { userDao.method(); } }
|
修改bean配置
- 通过
<property />
配置,实现setter注入
- 可以指定多个
<property />
配置,实现注入多个
name=""
:指定变量名(指定UserService.java
中UserDao userDao;
中的对象名)
ref=""
:指定变量值(指定applicationContext.xml
中的<bean id="userDao" class="com.dao.UserDao"/>
中bean的id或name)
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"> <property name="userDao" ref="userDao"/> <property name="" ref=""/> </bean>
</beans>
|
基本类型注入
直接赋值改为不赋值
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11
| package com.service;
public class UserService {
private int id; public void setId(int id) { this.id = id; } }
|
修改bean配置
- 通过
<property />
配置,实现注入
- 可以指定多个
<property />
配置,实现注入多个
name=""
:指定变量名
value=""
:指定变量值
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9
| <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="userService" class="com.service.UserService"> <property name="id" value="1"/> <property name="" value=""/> </bean>
</beans>
|
通过构造器注入
引用类型注入
new创建对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| package com.service;
import com.dao.UserDao;
public class UserService {
UserDao userDao;
public UserService(UserDao userDao) { this.userDao = userDao; }
public void method() { userDao.method(); } }
|
修改bean配置
- 通过
<constructor-arg />
配置,实现构造器注入
- 可以指定多个
<constructor-arg />
配置,实现注入多个
name=""
:指定变量名(指定UserService.java
中构造方法 public UserService(UserDao userDao) {}
中的形参名)
ref=""
:指定变量值(指定applicationContext.xml
中的<bean id="userDao" class="com.dao.UserDao"/>
中bean的id或name)
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11
| <?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="userDao" class="com.dao.UserDao" /> <bean id="userService" class="com.service.UserService"> <constructor-arg name="userDao" ref="userDao" /> <constructor-arg name="" ref="" /> </bean>
</beans>
|
基本类型注入
直接赋值改为不赋值
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
public class UserService {
private int id; public UserService(int id) { this.id = id; } }
|
修改bean配置
- 通过
<constructor-arg />
配置,实现构造器注入
- 可以指定多个
<constructor-arg />
配置,实现注入多个
name=""
:指定变量名
value=""
:指定变量值
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10
| <?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="userService" class="com.service.UserService"> <constructor-arg name="id" value="1" /> <constructor-arg name="" value="" /> </bean>
</beans>
|
解决形参名可能被修改的问题
- 如果所有形参的类型均不相同,可以采用指定变量类型的方式解耦
type=""
:指定变量类型
value=""
:指定变量值
1 2 3 4 5 6 7 8 9 10
| <?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="userService" class="com.service.UserService"> <constructor-arg type="int" value="1" /> <constructor-arg type="java.lang.String" value="" /> </bean>
</beans>
|
解决形参类型可能重复的问题
index=""
:指定形参顺序
value=""
:指定变量值
1 2 3 4 5 6 7 8 9 10
| <?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="userService" class="com.service.UserService"> <constructor-arg index="0" value="1" /> <constructor-arg index="" value="" /> </bean>
</beans>
|
通过setter自动装配
- 自动装配只能为引用类型自动装配
- 如果手动装配的配置和自动装配的配置同时出现,那么自动装配的配置会失效
引用类型注入
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import com.dao.UserDao;
public class UserService { UserDao userDao;
public void setUserDao(UserDao userDao) { this.userDao = userDao; }
public void method() { userDao.method(); } }
|
修改bean配置
- 添加被自动装配的bean配置
- 在需要自动装配的bean上添加
autowire=""
属性
autowire=""
指定自动装配方式
byType
:按类型
byName
:按名称
constructor
:使用构造方法
default
:默认
no
:不使用自动装配
按类型自动装配
- 在定义被自动装配的bean时,不能有多个相同类型的bean
- 如果是按类型自动装配,被自动装配的bean甚至可以不定义id
src/main/resources/applicationContext.xml1 2 3 4 5 6 7
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService" autowire="byType"/>
</beans>
|
按名称自动装配
- 被自动装配bean的id需要与set方法的属性名相同(setUserDao -> dao)
src/main/resources/applicationContext.xml1 2 3 4 5 6 7
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService" autowire="byName"/>
</beans>
|
通过setter多数据注入
数组类型注入
注入基本类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11
| package com.service;
public class UserService {
int[] array;
public void setArray(int[] array) { this.array = array; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<array></array>
:数组类型注入
<value></value>
:指定变量值
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userService" class="com.service.UserService"> <property name="array"> <array> <value>1</value> <value></value> </array> </property> </bean>
</beans>
|
注入引用类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11
| package com.service;
public class UserService {
UserDao[] array;
public void setArray(UserDao[] array) { this.array = array; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<array></array>
:数组类型注入
<ref bean=""/>
:指定bean对象的id
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"> <property name="array"> <array> <ref bean="userDao"/> </array> </property> </bean>
</beans>
|
List集合类型注入
注入基本类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.List;
public class UserService {
List<String> list;
public void setList(List<String> list) { this.list = list; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<list></list>
:List集合类型注入
<value></value>
:指定变量值
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userService" class="com.service.UserService"> <property name="list"> <list> <value>1</value> <value></value> </list> </property> </bean>
</beans>
|
注入引用类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.List;
public class UserService {
List<UserDao> list;
public void setList(List<UserDao> list) { this.list = list; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<list></list>
:List集合类型注入
<ref bean=""/>
:指定bean对象的id
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"> <property name="list"> <list> <ref bean="userDao"/> </list> </property> </bean>
</beans>
|
Set集合类型注入
注入基本类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.Set;
public class UserService {
Set<String> set;
public void setSet(Set<String> set) { this.set = set; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<set></set>
:Set集合类型注入
<value></value>
:指定变量值
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userService" class="com.service.UserService"> <property name="set"> <set> <value>1</value> <value></value> </set> </property> </bean>
</beans>
|
注入引用类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.Set;
public class UserService {
Set<UserDao> set;
public void setSet(Set<UserDao> set) { this.set = set; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<set></set>
:Set集合类型注入
<ref bean=""/>
:指定bean对象的id
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"> <property name="set"> <set> <ref bean="userDao"/> </set> </property> </bean>
</beans>
|
Map集合类型注入
注入基本类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.Map;
public class UserService {
Map<String, String> map;
public void setMap(Map<String, String> map) { this.map = map; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<map></map>
:Set集合类型注入
<entry key="" value=""/>
:指定键值对
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userService" class="com.service.UserService"> <property name="map"> <map> <entry key="k" value="v"/> <entry key="" value=""/> </map> </property> </bean>
</beans>
|
注入引用类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.Map;
public class UserService {
Map<String, UserDao> map;
public void setMap(Map<String, UserDao> map) { this.map = map; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<map></map>
:Set集合类型注入
<entry key="" value=""/>
:指定键值对,值为引用类型
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"> <property name="map"> <map> <entry key="k" value="userDao"/> <entry key="" value=""/> </map> </property> </bean>
</beans>
|
Properties类型注入
注入基本类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.Properties;
public class UserService {
Properties properties;
public void setProperties(Properties properties) { this.properties = properties; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<props></props>
:Set集合类型注入
<prop key=""></prop>
:指定键值对
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13
| <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="userService" class="com.service.UserService"> <property name="properties"> <props> <prop key="k">v</prop> <prop key=""></prop> </props> </property> </bean>
</beans>
|
注入引用类型数据
new对象改为不创建对象
src/main/java/service/UserService.java1 2 3 4 5 6 7 8 9 10 11 12
| package com.service;
import java.util.Properties;
public class UserService {
Properties properties;
public void setProperties(Properties properties) { this.properties = properties; } }
|
修改bean配置
- 通过
<property></property>
配置,实现setter注入
name=""
:指定变量名
<props></props>
:Set集合类型注入
<prop key=""></prop>
:指定键值对,值为引用类型
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <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="userDao" class="com.dao.UserDao"/> <bean id="userService" class="com.service.UserService"> <property name="properties"> <props> <prop key="k">userDao</prop> <prop key=""></prop> </props> </property> </bean>
</beans>
|
管理第三方的bean
添加依赖
pom.xml1 2 3 4 5
| <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency>
|
由Spring管理对象
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12
| <?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="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <property name="url" value="jdbc:mysql:///" /> <property name="username" value="" /> <property name="password" value="" /> </bean>
</beans>
|
获取并使用bean对象
src/main/java/com/Application.java1 2 3 4 5 6 7
| public class Application { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource dataSource = (DataSource) applicationContext.getBean("dataSource"); System.out.println(dataSource); } }
|
Spring实例化bean的方式
- 使用无参构造实例化bean对象
- 使用静态工厂实例化bean对象
- 使用实例工厂实例化bean对象
手动配置静态工厂方式获取bean对象
创建静态工厂类
src/main/java/com/factory/UserDaoFactory.java1 2 3 4 5 6 7 8 9
| package com.factory;
import com.dao.UserDao;
public class UserDaoFactory { public static UserDao getUserDao() { return new UserDao(); } }
|
修改bean配置
class=""
:指定工厂类的全局限定名
factory-method=""
:指定工厂类中获取对象的方法名
src/main/resources/applicationContext.xml1 2 3 4 5 6 7
| <?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="userDao" class="com.factory.UserDaoFactory" factory-method="getUserDao"/>
</beans>
|
手动配置实例工厂方式获取bean对象
创建静态工厂类
src/main/java/com/factory/UserDaoFactory.java1 2 3 4 5 6 7 8 9
| package com.factory;
import com.dao.UserDao;
public class UserDaoFactory { public UserDao getUserDao() { return new UserDao(); } }
|
修改bean配置
factory-bean=""
:指定工厂类bean的id
factory-method=""
:指定工厂类中获取对象的方法名
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8
| <?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="userDaoFactory" class="com.factory.UserDaoFactory"/> <bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"/>
</beans>
|
自动配置实例工厂方式获取bean对象
创建一个工厂类
- 创建一个工厂类,实现
FactoryBean<>
接口,在getObject()
方法中返回创建的 对象,在getObjectType()
方法中返回创建的对象的类型
FactoryBean<>
:指定创建的对象的类型作为泛型
src/main/java/com/factory/UserDaoFactory.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.factory;
import com.dao.UserDao; import org.springframework.beans.factory.FactoryBean;
public class UserDaoFactory implements FactoryBean<UserDao> { public UserDao getObject() throws Exception { return new UserDao(); } public Class<?> getObjectType() { return UserDao.class; } }
|
工厂类创建非单例的实例
- 默认工厂类创建的实例是单例的,通过重写
isSingleton()
方法,将返回值改为false,就可以创建出非单例的实例
src/main/java/com/factory/UserDaoFactory.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.factory;
import com.dao.UserDao; import org.springframework.beans.factory.FactoryBean;
public class UserDaoFactory implements FactoryBean<UserDao> { public UserDao getObject() throws Exception { return new UserDao(); } public Class<?> getObjectType() { return UserDao.class; } public boolean isSingleton() { return true; } }
|
修改bean配置
class=""
:配置工厂类的全局限定名
1 2 3 4 5 6 7
| <?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="userDao" class="com.factory.UserDaoFactory"/>
</beans>
|
bean的生命周期
- 初始化容器 -> 使用bean -> 关闭/销毁容器
- 初始化容器:创建对象 -> 执行构造方法 -> 执行属性注入(执行
set()
方法)-> 执行bean的初始化方法
- 使用bean:执行业务操作
- 关闭/销毁容器:执行销毁方法
手动配置生命周期方法
定义bean的生命周期方法
- 在类中定义一个用于初始化的方法,方法名任意,这个方法期望在bean对象创建后执行
- 在类中定义一个用于销毁的方法,方法名任意,这个方法期望在bean对象销毁前执行
src/main/java/com/dao/UserDao.java1 2 3 4 5 6 7 8 9 10 11
| public class UserDao {
public void init() { System.out.println("userDao.init()"); } public void destroy() { System.out.println("userDao.destroy()"); }
}
|
修改bean配置
init-method=""
:指定初始化方法的方法名
destroy-method=""
:指定销毁方法的方法名
src/main/resources/applicationContext.xml1 2 3 4 5 6 7
| <?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="userDao" class="com.dao.UserDao" init-method="init" destroy-method="destroy"/>
</beans>
|
关于销毁方法遇到的问题
- 正常情况下,
destroy()
方法不会被执行,因为关闭程序时JVM会直接关闭,所以不会执行destroy()
方法
- 如果想要执行
destroy()
方法`,可以手动关闭Spring容器或注册关闭钩子
手动关闭Spring容器
- 通过
ClassPathXmlApplicationContext
类中的close()
方法关闭Spring容器,这种方式比较暴力
- 手动关闭Spring容器的方法只能在程序运行结束的位置添加
1 2 3 4 5 6
| public class Application { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); applicationContext.close(); } }
|
注册关闭钩子
- 通过
ClassPathXmlApplicationContext
类中的registerShutdownHook()
方法来注册关闭钩子
- 注册关闭钩子的方法可以在任意位置添加
1 2 3 4 5 6
| public class Application { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); applicationContext.registerShutdownHook(); } }
|
自动配置生命周期方法
定义bean的生命周期方法
- 在类中实现
InitializingBean
接口,并重写afterPropertiesSet()
方法,在方法中定义bean对象set()
方法执行之后执行的操作
- 在类中实现
DisposableBean
接口,并重写destroy()
方法,在方法中定义bean对象销毁前执行的操作
src/main/java/com/dao/UserDao.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.dao;
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean;
public class UserDao implements InitializingBean, DisposableBean {
public void afterPropertiesSet() throws Exception { System.out.println("userDao.afterPropertiesSet()"); } public void destroy() throws Exception { System.out.println("userDao.destroy()"); } }
|
修改bean配置
1 2 3 4 5 6 7
| <?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="userDao" class="com.dao.UserDao"/>
</beans>
|
Spring读取properties文件
创建properties配置文件
src/main/resources/druid.properties1 2 3 4
| url.driverClassName=com.mysql.cj.jdbc.Driver url.url=jdbc:mysql:///demo url.username= url.password=
|
创建xml配置文件
- 创建Spring配置文件,并修改
<beans></beans>
中的属性,开启context命名空间
- 使用context空间加载properties文件
- 将Spring配置文件中定义的值改为属性占位符
${}
<context:property-placeholder/>
location=""
:指定properties的文件路径,相对路径的根目录是src/main/resources
location="<properties_file_1>,<properties_file_2>"
:引入多个配置文件时,用逗号隔开
location="*.properties"
:引入全部
location="classpath:*.properties"
:从当前项目中(缺省值),引入全部
location="classpath*:*.properties"
:从当前项目和引入的jar包中,引入全部
system-properties-mode=""
:系统属性模式
NEVER
:不加载系统属性
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${url.driverClassName}" /> <property name="url" value="${url.url}" /> <property name="username" value="${url.username}" /> <property name="password" value="${url.password}" /> </bean>
</beans>
|
容器的操作
容器的加载
通过类路径加载配置文件
- 相对路径的根目录是
src/main/resources
,多个配置文件用逗号隔开
1 2 3
| ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml", "applicationContext.xml");
|
通过文件系统路径加载配置文件
- 相对路径的根目录是项目的根目录,多个配置文件用逗号隔开
1 2 3
| ApplicationContext applicationContext = new FileSystemXmlApplicationContext("src/main/resources/applicationContext.xml");
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("src/main/resources/applicationContext.xml", "src/main/resources/applicationContext.xml");
|
1 2 3
| ApplicationContext applicationContext = new FileSystemXmlApplicationContext("/root/applicationContext.xml");
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("/root/applicationContext.xml", "/root/applicationContext.xml");
|
容器中获取bean对象
获取Object类型bean对象
- 获取Object类型bean对象,可以强制类型转换
1
| DataSource dataSource = (DataSource) applicationContext.getBean("dataSource");
|
获取指定类型的bean对象
1
| DataSource dataSource = applicationContext.getBean("dataSource", DataSource.class);
|
按照类型自动获取bean对象
1
| DataSourc e dataSource = applicationContext.getBean(DataSource.class);
|
BeanFactory
- 旧版本Spring容器使用的是BeanFactory类型的对象
Object.class
:根据数据类型获取bean对象
1 2 3
| Resource resource = new ClassPathResource("applicationContext.xml"); BeanFactory beanFactory = new XmlBeanFactory(resource); Object obj = beanFactory.getBean(Object.class);
|
- 区别
- ApplicationContext默认是立即加载bean,立即执行构造方法
- BeanFactory默认是延迟加载bean,延迟执行构造方法
bean的相关配置
id=""
:定义bean的名称
name=""
:定义bean的别名,多个别名之间可以用逗号、分号、空格分隔
class=""
:定义bean的类型
scope=""
:定义bean的作用范围
singleton
:缺省值,单例的
prototype
:非单例的
init-method=""
:指定生命周期的初始化方法的方法名
destory-method=""
:指定生命周期的销毁方法的方法名
autowire=""
:指定自动装配方式
byType
:按类型
byName
:按名称
constructor
:使用构造方法
default
:默认
no
:不使用自动装配
factory-bean=""
:指定实例工厂bean的id
factory-method=""
:指定bean工厂方法的方法名,通常用于静态工厂或实例工厂
lazy-init=""
:ApplicationContext实现延迟加载
true
:开启延迟加载
false
:缺省值,关闭延迟加载
src/main/resources/applicationContext.xml1 2 3 4 5 6 7 8 9 10 11 12
| <bean id="" name="" class="" scope="" init-method="" destroy-method="" autowire="" factory-method="" factory-bean="" lazy-init="" />
|
异常
No Such B ean Definition Exception
NoSuchBeanDefinitionException
:没找到bean定义,获取bean对象时指定的bean名称与xml中配置的bean名称不相同
BeanCreateException
:bean创建异常,无参构造不存在导致bean对象创建失败
完成
参考文献
哔哩哔哩——黑马程序员