前半个月一直在应付期中考试,快被折磨似了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);