bean
bean配置
-
导入spring的坐标(pom.xml内)spring-context,对应版本5.2.10RELEASE
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency>
-
配置bean
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"/>
-
id属性标示给bean起名字
-
class属性表示给bean定义类型
-
name属性表示给bean取别名,可以有多个名字,用, ; 或者 空格 分隔
-
scope属性控制bean的作用范围,可选singleton(单例)和prototype(非单例),默认为singleton(单例)
-
BookService bookDao1 = (BookService) ctx.getBean("bookDao"); BookService bookDao2 = (BookService) ctx.getBean("bookDao");
- 单例时bookDao1和bookDao2是同一个对象
- 非单例时bookDao1和bookDao2是不同对象
-
- 获取IoC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- 获取bean
BookService bookService = (BookService) ctx.getBean("bookService");
-
获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常
NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: No bean named 'bookServiceImpl' available
- 删除业务层中使用new的方式创建的dao对象
//private BookDao bookDao = new BookDaoImpl();
private BookDao bookDao;
- 提供对应的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
- 配置service与dao的属性
<bean id="bookService" class="com.jihua.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
- property标签表示配置当前bean的属性
- ref属性表示参照哪一个bean
- name属性表示配置哪一个具体的属性,其实就是set方法调用
set×××()
函数时的×××
适合交给容器进行管理的bean
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
不适合交给容器进行管理的bean
- 封装实体的域对象
实例化bean的三种方式
1. 构造方法实例化bean
-
调用无参构造方法,无论是public还是private都可以访问到
-
配置
-
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"/>
-
-
无参构造方法如果不存在,将抛出异常
BeanCreationException
2. 静态工厂实例化bean
-
public class OrderDaoFactory { public static OrderDao get0rderDao(){ return new OrderDaoImpl(); } }
-
需要在配置中指明工厂创建方法
factory-method
-
<bean id="orderDao" factory-method="getOrderDao" class="com.jihua.factory.0rderDaoFactory"/>
3. 实例工厂实例化bean
-
public class UserDaoFactory { public UserDao getUserDao(){ return new UserDaoImpl(); } }
-
需要在配置中指明工厂创建方法
factory-method
和factory-bean
-
<bean id="userDaoFactory" class="com.jihua.factory.UserDaoFactory" /> <bean id="userDao" factory-method="getUserDao" factory-bean="userDaoFactory"/>
4. 使用Factory实例化bean
- 实例工厂需要实现
FactoryBean<?>
,泛型为要生成的对象类型
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
//代替原始实例工厂中创建对象的方法
public UserDao getobject() throws Exception {
return new UserDaoImpl();
}
public class<?> getobjectType() {
return UserDao.class;
}
//控制创建的对象是否为单例(true为单例,false为非单例),一般不写,不写该方法则默认为(true单例)
public boolean issingleton() {
return true;
}
}
-
配置文件只需要实现该工厂bean即可
-
<bean id="userDao" class="com.jihua.factory.UserDaoFactoryBean"/>
-
多数框架使用的方法
bean的生命周期
生命周期
初始化容器
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(set操作)
- 执行bean初始化方法
使用bean
- 执行业务操作
关闭/销毁容器
- 执行bean销毁方法
生命周期控制
1. 配置文件方法
-
提供生命周期控制方法
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.jihua.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory" />
2. 接口控制方式
-
实现InitializingBean,DisposableBean接口
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean{ public void save() { System.out.println( "book service save ..."); } //销毁 public void afterPropertiesSet( ) throws Exception { System.out.print1n( "afterPropertiesset" ); } //初始化 public void destroy() throws Exception { System.out.println( "destroy" ); } }
3.销毁
-
销毁一般由tomcat服务器调用
-
不使用tomcat的时候使用
-
- 手工关闭容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); ctx.close();
-
- 注册关闭钩子
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); ctx.
-
依赖注入
- 依赖注入方式
- setter注入
- 简单类型
- 引用类型
- 构造器注入
- 简单类型
- 引用类型
- setter注入
setter注入
-
引用类型
-
在bean中定义引用类型属性并提供可访问的set方法
public class BookServiceImpl implements BookService{ private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } }
-
配置中使用property标签ref属性注入引用类型对象
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl" /> <bean id="bookService" class="com.jihua.service.impl.BookServiceImpl"> <property name="bookDao" ref="bookDao" /> </bean>
-
-
简单类型
-
在bean中定义引用类型属性并提供可访问的set方法
private int connectionNum; private String connectionName; public void setConnectionNum(int connectionNum) { this.connectionNum = connectionNum; } public void setConnectionName(String connectionName) { this.connectionName = connectionName; }
-
配置中使用property标签value属性注入简单类型数据
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"> <property name="connectionNum" value="10" /> <property name="connectionName" value="10" /> </bean>
- Spring内部自动处理数据类型
-
构造器注入
传统写法
-
提供有参构造方法
private BookDao bookDao; private int connectionNum; private String connectionName; public BookServiceImpl(BookDao bookDao, int connectionNum, String connectionName) { this.bookDao = bookDao; this.connectionNum = connectionNum; this.connectionName = connectionName; }
-
使用constructor-arg标签value,ref属性注入数据
<bean id="bookService" class="com.jihua.service.impl.BookServiceImpl"> <constructor-arg name="bookDao" ref="bookDao" /> <constructor-arg name="connectionName" value="mysql" /> <constructor-arg name="connectionNum" value="10" /> </bean>
解耦合写法——参数适配
-
在constructor-arg标签中使用type属性按照数据类型注入
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"> <constructor-arg type="int" value="10" /> <constructor-arg type="java.lang.String" value="mysql"/> </ bean>
-
在constructor-arg标签中使用index属性按照参数顺序注入
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl"> <constructor-arg index="1" value="10" /> <constructor-arg index="0" value="mysql"/> </ bean>
依赖注入方式选择
- 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
- 可选依赖使用setter注入进行,灵活性强
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
- 自己开发的模块推荐使用setter注入
依赖自动装配
-
IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
-
自动装配方式
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
-
配置中使用bean标签autowire属性设置自动装配的类型
<bean id="bookDao" class="com.jihua.dao.impl.BookDaoImpl" /> <bean id="bookService" class="com.jihua.service.impl.BookServiceImpl" autowire="byType"/>
自动装配特征:
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时( byType )必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时( byName )必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于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>jihua</value> <value>boxuegu</value> </list> </property>
-
注入Set对象
<property name="set"> <set> <value>itcast</value> <value>jihua</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>
加载properties文件
-
加载文件
-
开启命名空间
在applicationContext.xml文件中:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd ">
-
使用context空间加载properties文件
在applicationContext.xml文件中:
<context:property-placeholder location="jdbc.properties"/>
-
-
使用属性
-
使用
${}
读取加载的属性值<property name="username" value="${jdbc.username}"/>
-
-
注意事项
-
不加载系统属性
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
-
加载多个properties文件
<context:property-placeholder location="jdbc.properties,msg.properties"/>
-
加载所有properties文件
<context:property-placeholder location="*.properties" />
-
加载properties文件标准格式
<context:property-placeholder location="classpath:*.properties"/>
-
从类路径或jar包中搜索并加载properties文件
<context:property-placeholder location="classpath*:*.properties" >
-