前半个月一直在应付期中考试,快被折磨似了orz
文章目录
- Spring
- IoC(Inversion of Control) 控制反转与DI(Dependency Injection)依赖注入
- bean相关
- bean配置
- bean实例化
- bean的生命周期
- 依赖注入相关
- 依赖注入方式
- 依赖自动装配
- 容器
- 创建容器
- 获取bean
Spring
IoC(Inversion of Control) 控制反转与DI(Dependency Injection)依赖注入
-
IoC(Inversion of Control) 控制反转
- 使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转(降低程序的耦合度)
-
Spring技术对IoC思想进行了实现
-
Spring提供了一个容器,称为IoC容器,用来充当思想中的“外部”
-
IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中被称为Bean
-
-
DI(Dependency Injection) 依赖注入
- 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
以上操作的目标:充分解耦
bean相关
bean配置
-
bean基础配置
-
id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一
-
class:bean的类型,即配置的bean的全路径类名
-
例子
-
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
- bean的别名
- name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔
- 例子
<bean id="bookService" name="service service4 bookEbi" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
- bean的作用范围
- scope:为bean设置作用范围,可选值为单例singleton,非单例prototype,若不写scope,则默认是单例对象
- 例子
<bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>
bean实例化
使用FactoryBean的方式实例化bean对象
- 实现FactoryBean接口,指定创建的泛型对象
//FactoryBean创建对象
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
public Class<?> getObjectType() {
return UserDao.class;
}
// 控制创建的bean是单例的还是非单例的,通常都是单例的
public boolean isSingleton() {
return true;
}
}
- 配置
<!--方式四:使用FactoryBean实例化bean-->
<!--注意,这种构造方法创建的不是FactoryBean对象,而是FactoryBean对象中的getObject对象-->
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
bean的生命周期
-
初始化容器
- 1.创建对象(内存分配)
- 2.执行构造方法
- 3.执行属性注入(set操作)
- 4.执行bean初始化方法
-
使用bean
- 执行业务操作
-
关闭/销毁容器
- 执行bean销毁方法
-
bean的销毁时机
-
容器关闭前触发bean的销毁
-
关闭容器方式:
- 手动关闭容器
ConfigurableApplicationContext接口close()操作
- 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
ConfigurableApplicationContext接口registerShutdownHook()操作
-
public class AppForLifeCycle {
public static void main( String[] args ) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
//注册关闭钩子函数,在虚拟机退出之前回调此函数,关闭容器
//ctx.registerShutdownHook();
//关闭容器
ctx.close();
}
}
依赖注入相关
依赖注入方式
-
向一个类中传递数据的方式有几种?
- 普通方法(set方法)
- 构造方法
-
依赖注入描述了在容器中建立bean和bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢?
- 引用类型
- 简单类型(基本数据类型与String)
-
依赖注入方式
-
setter注入
-
简单类型
- 在bean中定义引用类型属性并提供可访问的set方法
public class BookDaoImpl implements BookDao { private String databaseName; // 数据库名称 private int connectionNum; // 数据库连接数量 //setter注入需要提供要注入对象的set方法 public void setConnectionNum(int connectionNum) { this.connectionNum = connectionNum; } //setter注入需要提供要注入对象的set方法 public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } }
- 配置中使用property标签value属性注入简单类型数据
<!--注入简单类型--> <!--对bookDao进行配置--> <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"> <!--property标签:设置注入属性--> <!--name属性:设置注入的属性名,实际是set方法对应的名称--> <!--value属性:设置注入简单类型数据值--> <property name="connectionNum" value="100"/> <property name="databaseName" value="mysql"/> </bean>
-
引用类型
- 在bean中定义引用类型属性并提供可访问的set方法
public class BookServiceImpl implements BookService{ private BookDao bookDao; private UserDao userDao; //setter注入需要提供要注入对象的set方法 public void setUserDao(UserDao userDao) { this.userDao = userDao; } //setter注入需要提供要注入对象的set方法 public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } }
- 配置中使用property标签ref属性注入引用类型对象
<!--注入引用类型--> <!--对bookService进行配置--> <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"> <!--property标签:设置注入属性--> <!--name属性:设置注入的属性名,实际是set方法对应的名称--> <!--ref属性:设置注入引用类型bean的id或name--> <property name="bookDao" ref="bookDao"/> <property name="userDao" ref="userDao"/> </bean>
-
-
构造器注入
- 简单类型
- 引用类型
-
依赖自动装配
-
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
-
自动装配方式
- 按类型(常用)
- 按名称
- 按构造方法
-
配置中使用bean标签autowire属性设置自动装配的类型
<!--id在自动装配时可以省略不写-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
一些细节需要注意
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时**(byType)**必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时**(byName)**必须保障容器中具有指定名称的bean,因为变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
容器
创建容器
- 类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- 文件路径加载配置文件
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\Code\\java\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");
- 加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");
获取bean
- 使用bean名称获取
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
- 使用bean名称获取并指定类型
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
- 使用bean类型获取(容器中这个类型的bean只能有一个)
BookDao bookDao = ctx.getBean(BookDao.class);