Spring-Day01— IOC&DI
Spring-Day1 — IOC&DI
学什么
简化开发: Spring框架中提供了两个大的核心技术
- IOC
- AOP
核心概念
IOC & IOC容器 & Bean
- IOC(Inversion of Control)控制反转
- 不自己new对象,交给容器new – 解耦
- IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象
- 被创建或被管理的对象在IOC容器中统称为Bean
DI
- (Dependency Injection)依赖注入
- 建立容器中对象与对象之间的绑定关系
- service运行需要依赖dao对象
案例
解耦BookDao
pom.xml添加依赖
添加案例中需要的类
添加spring配置文件applicationContext.xml
<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">
<!--1.导入spring的坐标spring-context-->
<!--2.配置bean-->
<!--bean标签标示配置bean
id属性标示给bean起名字
class属性表示给bean定义类型
注意class不要写成接口类而是实现类,因为bean要找对象
-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
</beans>获取IOC容器、从容器中获取对象进行方法调用
public class App {
public static void main(String[] args) {
//获取IOC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//getBean() 方法获取的 Bean 的标识符(id 或 name 属性的值),返回的是一个通用的 Object 类型,我们需要将其转换为 BookService 类型
// BookDao bookDao = (BookDao) ctx.getBean("bookDao");
// bookDao.save();
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}运行程序测试
解耦BookService
去除BookServiceImpl中的new,为属性提供setter方法
public class BookServiceImpl implements BookService {
//删除业务层中使用new的方式创建的dao对象
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
//提供对应的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}修改配置完成注入
<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标签标示配置bean
id属性标示给bean起名字
class属性表示给bean定义类型-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<!--配置server与dao的关系-->
<!--property标签表示配置当前bean的属性
name属性表示配置哪一个具体的属性/对象名称
ref属性表示参照哪一个bean-->
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>运行程序
关于bean
bean的基础配置
配置别名 name
<!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔--> |
配置范围(是否为单例) scode
<!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype--> |
bean的实例化
构造方法实例化 — 无参构造方法
在BookDaoImpl类中添加一个无参构造函数,并打印一句话,方便观察结果
静态工厂实例化 — 了解即可
实例工厂化 — 额额不太懂
- 准备一个Dao和DaoImpl类
- 创建一个工厂类OrderDaoFactory并提供一个普通方法
public class UserDaoFactory {
}
}
- 创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
//替代UseDaoFactory的getUserDao方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
//返回所创建类的Class对象
public Class<?> getObjectType() {
return UserDao.class;
}
}
配置文件添加
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
编写AppForInstanceUser运行类,在类中通过工厂获取对象
public class AppForInstanceUser {
public static void main(String[] args) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
}
}
bean的生命周期
bean对象从创建到销毁的整体过程
初始化容器
- 1.创建对象(内存分配)
- 2.执行构造方法
- 3.执行属性注入(set操作)
- 4.执行bean初始化方法
使用bean
- 执行业务操作
关闭/销毁容器
- 执行bean销毁方法
代码实现
- 1.init&destory
//添加两个接口`InitializingBean`, `DisposableBean`并实现接口中的两个方法`afterPropertiesSet`和`destroy`
//这样就不用在配置文件里面配置`init-method`和`destroy-method`
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
public void destroy() throws Exception {
System.out.println("service destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("service init");
}
}- 2.close —执行destroy方法的内容
//ApplicationContext中没有close方法,需要将ApplicationContext更换成ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
//运行程序,就能执行destroy方法的内容
ctx.close();3.注册钩子关闭容器 — 执行destroy方法的内容
ctx.registerShutdownHook();
DI
相关内容
setter注入
- 简单类型
<bean ...>
<property name="" value=""/>
</bean> - 引用类型
<bean ...>
<property name="" ref=""/>
</bean>
构造器注入
- 简单类型
<bean ...>
<constructor-arg name="" index="" type="" value=""/>
</bean> - 引用类型
<bean ...>
<constructor-arg name="" index="" type="" ref=""/>
</bean>
自动配置
- 不用写配置文件了
- 类型
按类型(常用)
<bean class="com.itheima.dao.impl.BookDaoImpl"/> |
按名称 — 有多个相同类型的对象
<bean class="com.itheima.dao.impl.BookDaoImpl"/> |
按构造方法
集合注入
数组类型数据
<property name="array"> |
注入List类型数据
<property name="list"> |
注入Set类型数据
<property name="set"> |
注入Map类型数据
<property name="map"> |
注入Properties类型数据
<property name="properties"> |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 炫仔的Blog!