IOC作用:管理service和dao,要通过配置文件将被管理的对象告知IOC容器,
操作步骤:
1.需要先导入坐标
<dependencies>
<!--导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
</dependencies>
2.需要定义接口和实现类 3.创建spring配置文件applicationContext.xml 4.在配置文件中配置对应的类作为spring管理的bean对象
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
<!--bean标签:表示配置bean
id属性:表示给bean起名字
class属性:表示给bean定义类型
-->
注意事项:bean标签中的id属性在同一个IOC容器中不能重复
5.初始化IOC容器,通过容器获取Bean对象
//创建IOC容器对象,加载spring核心配置文件
ApplicationContext apcx = new
ClassPathXmlApplicationContext("applicationContext.xml");
//获取对应的Bean对象
AccountDao accountDao = (AccountDao) apcx.getBean("bookService");
//调用Bean对象的方法
accountDao.save();
DI作用:基于IOC管理bean
实现步骤: 1.删除使用new创建的对象代码
private BookDao bookDao = new BookDaoImpl(); 保留private BookDao bookDao 2.提供对应的setter方法 3在配置文件中配置service和dao的关系
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<!--配置server与dao的关系
property标签:表示配置当前bean的属性
name属性:表示配置哪一个具体的属性
ref属性:表示参照哪一个bean
-->
<property name="bookDao" ref="bookDao"/>
</bean>
Bean起别名使用name属性,定义多个名字使用逗号或者空格分隔 Bean的scope属性定义Bean作用范围,默认值为singleton表示单列,prototype表示非单列。意思是多次获取Bean对象如果打印的地址值相同表示单列,不同表示非单列:表示多次获取的对象是同一个
Bean实例化的三种方法
方法1.空参构造:在实现类中定义空参构造,只要不定义带参构造,那么实体类默认的构造方法就是空参构造
方法2.静态工厂: (1)创建OrderDao接口和OrderDaoImpl实现类
public interface OrderDao {
public void save();
}
public class OrderDaoImpl implements OrderDao {
public void save() {
System.out.println("order dao save ...");
}
}
(2)创建OrderDaoFatory工厂类
//静态工厂创建对象
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
System.out.println("factory setup....");
return new OrderDaoImpl();
}
(3)在配置文件中使用静态工厂实例化bean
方法3.实例工厂 (1)创建UserDao接口和UserDaoImpl实现类
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("user dao save ...");
}
}
(2)创建UserDaoFactory工厂类
//实例工厂创建对象
public class UserDaoFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
(3)在配置文件中配置
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
Bean生命周期
生命周期的控制
方法1.使用配置文件定义Bean的属性init-method和destroy-method对应的方法
(1)在实现类中定义两个方法,一个是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...");
}
}
(2)在配置文件中定义Bean的init-method和destroy-method的属性
<!--init-method:设置bean初始化生命周期回调函数,此处填写init方法名-->
<!--destroy-method:设置bean销毁生命周期回调函数,仅适用于单例对象,此处填写destory方法名-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
方法2.实现类实现InitializingBean, DisposableBean接口,然后重写接口中的方法
public void destroy() throws Exception {
System.out.println("service destroy");
}
public void afterPropertiesSet() throws Exception {
System.out.println("service init");
}
Bean销毁时机,在关闭容器前销毁bean
关闭容器的方法
方法1.手工关闭ConfigurableApplicationContext接口close()操作 方法2.注册关闭钩子,在虚拟机退出之前,先关闭容器,ConfigurableApplicationContext接口registerShutdownHook()操作
依赖注入
依赖注入的两种方式
1.setter注入(简单类型,引用类型(常用)) setter注入需要注意在实现类中定义set方法
2.构造器注入(简单类型,引用类型) 构造器注入可以使用constructor-arg标签type属性设置按参数类型主注入,也可以使用index属性设置按照参数的位置注入
?
依赖注入的选择 1.强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现 2.可选依赖使用setter注入进行,灵活性强 3.spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨 4.如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入 5.实际可开发过程中还要根据实际情况分析,如果受操控对象没有提供setter方法就必须使用构造器注入 6.推荐使用setter注入 ?
自动装配:根据bean所依赖的资源所在容器中自动查找并注入到bean中的过程称为自动装配 ?
自动装配的方式
根据类型(常用) 根据名称 根据构造方法 不启用自动装配
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
依赖自动装配特征
1.自动装配用于引用类型依赖注入,不能对简单类型进行操作 2.使用根据类型装配时(byType)必须保证容器中相同类型的bean唯一,推荐使用 3.使用根据名称装配时(byName)必须保证容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用 4.自动装配优先级低于setter注入和构造器注入,同时出现时自动装配配置失效 ?
集合注入
<property name="array">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
注入List类型数据
<property name="list">
<list>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>chuanzhihui</value>
</list>
</property>
注入Set类型数据
<property name="set">
<set>
<value>itcast</value>
<value>itheima</value>
<value>boxuegu</value>
<value>boxuegu</value>
</set>
</property>
?注入Map类型数据
<property name="map">
<map>
<entry key="country" value="china"/>
<entry key="province" value="henan"/>
<entry key="city" value="kaifeng"/>
</map>
</property>
注入Properties类型数据
<property name="properties">
<props>
<prop key="country">china</prop>
<prop key="province">henan</prop>
<prop key="city">kaifeng</prop>
</props>
</property>
|