2022-09-27 spring
目录
spring
前言
代码书写现状
耦合度偏高
解决方案
使用对象时,在程序上不要主动使用new产生对象,转换为由外部提供对象
概念
IoC(Inversion of Control)控制反转
使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
- spring技术对IoC思想进行了实现
- spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”
- IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
DI(Dependency Injection)依赖注入
在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
目标
充分解耦
- 使用IoC容器管理bean(IoC)
- 在IoC容器内将有依赖关系的bean进行关系绑定(DI)
最终效果
使用对象时不仅可以直接从IoC容器中获取,并且获取到的bean已经绑定了所有的依赖关系
步骤
- 导入spring的坐标spring-context,对应版本是5.2.10.RELEASE
- 配置bean
bean标签表示配置bean
id属性表示给bean起名字
class属性表示给bean定义类型
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
- 获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- 获取bean
BookService bookService = (BookService) ctx.getBean("bookService");
- 删除业务层中使用new的方式创建的Dao对象
private BookDao bookDao;
- 提供对应的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
- 配置service与dao的关系
property标签表示配置当前bean的属性
name属性表示参照哪一个bean
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"></property>
</bean>
bean
别名
定义bean的别名,可定义多个,使用逗号(,)分号(;)空格( )分隔
<bean id="bookService" name="service service2 bookEbi" class="com.itheima.service.impl.BookServiceImpl"></bean>
注意:获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionException
bean的配置
创建出来的对象时非单例的
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"></bean>
创建单例的对象
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="singleton"></bean>
默认是单例的
适合交给容器进行管理的bean
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
不适合交给容器进行管理的bean
- 封装实体的域对象
bean实例化
- bean本质上就是对象,创建bean使用构造方法完成
实例化bean的三种方式
构造方法
- 提供可访问的构造方法
- 无参构造方法如果不存在,将抛出异常BeanCreationException(bean创建异常)
静态工厂(了解)
- 静态工厂
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
return new OrderDaoImpl();
}
}
- 配置
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"></bean>
实例工厂(了解)
- 实例工厂
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
- 配置
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"></bean>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"></bean>
实例化bean的第四种方式-----FactoryBean(实用)
- FactoryBean
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
// 代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
public Class<?> getObjectType() {
return UserDao.class;
}
}
- 配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"></bean>
bean的生命周期
生命周期:从创建到消亡的完整过程
bean生命周期:bean从创建到销毁的整体过程
bean生命周期控制:在bean创建后到销毁前做一些事情
- 初始化容器
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(set操作)
- 执行bean初始化方法
- 使用bean
- 执行业务操作
- 关闭/销毁容器
- 执行bean销毁方法
提供生命周期控制
- 提供生命周期控制方法
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save...");
}
// 表示bean初始化对应的操作
public void init(){
System.out.println("init...");
}
// 表示bean销毁前对应的操作
public void destory(){
System.out.println("destory...");
}
}
- 配置生命周期控制方法
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"></bean>
接口控制(了解)
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public void save() {
System.out.println("book service save...");
}
public void setBookDao(BookDao bookDao) {
System.out.println("set...");
this.bookDao = bookDao;
}
public void destroy() throws Exception {
System.out.println("service destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("service init");
}
}
bean销毁时机
- 容器关闭前触发bean的销毁
- 关闭容器方式:
- 手工关闭容器
ConfigurableApplicationContext接口close()操作 - 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
ConfigurableApplicationContext接口registerShutdownHook()操作
- 手工关闭容器
public class AppForLifeCycle {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.close();
ctx.registerShutdownHook(); // 第二种方法
}
}