本文观看前请移步(10条消息) 新星计划-----又见Spring----05_告别牛奶的博客-CSDN博客查看完整过程。
目录
1,配置Bean
bean其实就是对象,在spring容器中被管理的形式。
配置bean有三种方式:
1 ,bean基础配置
2,bean别名配置
3,bean作用范围配置
bean标签,所属beans标签,为了定义spring核心容器管理的对象。
配置基本格式如下:
<beans>
<bean/>(DAO层实现)
<bean></bean>(service层实现)
</beans>
bean标签的属性:
id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一 class:bean的类型,即配置的bean的全路径类名。
1,基础格式(名称bean)
示例:
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"></bean>
2,别名配置(名称name)
<bean id="bookDao" name="dao bookDaoImpl" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean name="service,bookServiceImpl" class="com.itheima.service.impl.BookServiceImpl"/>
本来唯一确定的id,可以用逗号,空格,分号来进行间隔,这样可以多定义bean标识,如果没有找到,则抛出NoSuchBeanDefinitionException,返回No bean named 'bookServiceImpl' available。
3,作用范围配置(名称scope)
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype" />
可选范围:singleton,单例模式(默认情况下);prototype(非单例模式)
适合交给容器进行管理的bean:
表现层对象;业务层对象,数据层对象,工具对象。
不适合交给容器管理的bean:
封装实体的域对象。
2,bean如何创建,如何实例化
创建bean使用构造方法(构造方法是系统本身提供的,没有方法体和参数)完成,无参构造方法如果不存在,将抛出异常BeanCreationException。
实例化bean共有三种方式:
1,常用方法:构造方法
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("book constructor is running ...");
}
public void save() {
System.out.println("book dao save ...");
}
}
配置bean上面已经讲过:
<bean
id="bookDao"
class="com.itheima.dao.impl.BookDaoImpl"
/>
2,静态工厂
public class OrderFactory{
public static OrderDao getOrderDao(){
return new OrderDaoImpl();
}
}
配置:
<bean
id="orderDao"
factory-method="getOrderDao" class="com.itheima.factory.OrderDaoFactory"
/>
3.1,实例工厂
public class UserFactory{
public UserDao getUserDaoo(){
return new UserImpl();
}
}
配置:
<bean id="userDaoFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean
id="userDao"
factory-method="getUserDao"
factory-bean="userDaoFactory"
/>
3.2 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"
/>
3,bean的生命周期及控制
1),bean的生命周期即bean从创建到销毁的一个完整过程。
配置:init-method,destory-method;
接口:InitializingBean,DisposableBean;
关闭容器:configurableApplicationContext接口操作close()orregisterShutdownHook()
bean生命周期详解:
(1)初始化容器
1,创建对象(内存分配)
2,执行构造方法
3,执行属性注入(set操作)
4,执行bean初始化方法
(2)使用bean,执行业务操作
(3)关闭销毁容器,执行bean销毁方法
2),控制bean的生命周期就是在bean被销毁之前做一些事情。
提供生命周期控制方法:
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
public void init(){
System.out.println("book init ...");
}
public void destory(){
System.out.println("book destory ...");
}
}
配置生命周期控制方法:
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
bean的销毁时机:容器关闭之前出发bean的销毁。
关闭容器的两种方式:
手头关闭容器
public class AppForLifeCycle {
public static void main( String[] args ) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
ctx.close();
}
}
&注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机。
4,依赖注入的两种方式
Java中的数据类型分为基本数据类型和引用类型。基本数据类型例如,整型,浮点型,长整型等,而引用类型有三种,字符串,数组,对象。想要向类中传递参数,通过是set方法和构造方法。
所以,向bean中注入依赖分为两种方法:setter注入(简单类型,引用类型)和构造器注入(简单类型和引用类型)。
1,setter注入:
setter注入引用类型:
在bean中定义引用类型(如对象 bookDao)属性并提供可访问的set方法:
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
配置中使用property标签ref属性注入引用类型对象
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
setter注入简单类型:
在bean中定义简单类型(如整型 connnectionNumber)属性并提供可访问的set方法
public class BookDaoImpl implements BookDao {
private int connectionNumber;
public void setConnectionNumber(int connectionNumber) {
this.connectionNumber = connectionNumber;
}
}
配置中使用property标签value属性注入简单类型数据
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
2,构造器注入
构造器注入引用类型
在bean中定义引用类型属性(如对象bookDao)并提供可访问的构造方法:
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public BookServiceImpl(BookDao bookDao) {
this.bookDao = bookDao;
}
}
配置中使用constructor-arg标签ref属性注入引用类型对象:
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
<constructor-arg name="bookDao" ref="bookDao"/>
</bean>
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
构造器注入简单类型:
在bean中定义简单类型属性(如整型connextionNumber)并提供可访问的构造方法:
public class BookDaoImpl implements BookDao {
private int connectionNumber;
public void setConnectionNumber(int connectionNumber) {
this.connectionNumber = connectionNumber;
}
}
配置中使用constructor-arg标签value属性注入简单类型数据:
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
<constructor-arg name="connectionNumber" value="10"/>
</bean>
5,依赖注入方式的选择
1,强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
2,可选依赖使用setter注入进行,灵活性强 Spring框架倡导使用构造器,
3,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
4,实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
5,自己开发的模块推荐使用setter注入
6,依赖自动装配
上节介绍了依赖的手动配置,其实依赖还可以自动装配:
1,按类型(常用)
2,按名称
3,按构造方法
但是:
1,自动装配优先级比setter和构造器注入要低,同时出现时,会被晾在一边儿而失效;
2,在自动装配只能作用于引用类型,不能用于简单类型。
3,自动装配可以按照bean标签的autowire属性,它的值有两个,byType(必须保障容器中相同类型的bean唯一,推荐)和byName(必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐)
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>