Spring框架学习(二)—Ioc容器—Bean管理——基于XML(续集)
1、IOC 操作 Bean 管理(FactoryBean)
Spring 有两种类型 bean,一种普通 bean,另外一种工厂 bean(FactoryBean)
普通 bean:在配置文件中定义 bean 类型就是返回类型
工厂 bean:在配置文件定义 bean 类型可以和返回类型不一样 第一步 创建类,让这个类作为工厂 bean,实现接口 FactoryBean 第二步 实现接口里面的方法,在实现的方法中定义返回的 bean 类型
1 2 3 4 5 6 7 8 9 10 11
| public class MyBean implements FactoryBean<Course> {
@Override public Course getObject() throws Exception { Course course = new Course(); course.setCname("abc"); return course; }
}
|
1 2
| <bean id="myBean" class="com.atguigu.spring5.factorybean.MyBean"> </bean>
|
1 2 3 4 5 6 7
| @Test public void test3() { ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml"); Course course = context.getBean("myBean", Course.class); System.out.println(course); }
|
2、IOC 操作 Bean 管理(bean 作用域)
在 Spring 里面,默认情况下,bean 是单实例对象,下面进行作用域设置:
(1)在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
(2)scope 属性值 第一个值 默认值,singleton,表示是单实例对象 第二个值 prototype,表示是多实例对象
1 2 3
| <bean id="book" class="com.atguigu.spring5.collectiontype.Book" scope="prototype"> <property name="list" ref="bookList"></property> </bean>
|
(3)singleton 和 prototype 区别
a)singleton 单实例,prototype 多实例
b)设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象 ;设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建对象,在调用 getBean 方法时候创建多实例对象
3、IOC 操作 Bean 管理(bean 生命周期)
1、生命周期 :从对象创建到对象销毁的过程
2、bean 生命周期
(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(4)bean 可以使用了(对象获取到了)
(5)当容器关闭前触发bean的销毁(需要进行配置销毁的方法)
或:
· 初始化容器
1.创建对象(内存分配)
2.执行构造方法
3.执行属性注入(set操作)
4.执行bean的初始化方法
· 使用bean
1.执行业务
· 关闭/销毁容器
1.执行bean的销毁方法
3、演示 bean 生命周期(两种方式) :
(1)手动配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Orders { public Orders() { System.out.println("第一步 执行无参数构造创建 bean 实例"); } private String oname; public void setOname(String oname) { this.oname = oname; System.out.println("第二步 调用 set 方法设置属性值"); } public void initMethod() { System.out.println("第三步 执行初始化的方法"); } public void destroyMethod() { System.out.println("第五步 执行销毁的方法"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class MyBeanPost implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之前执行的方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("在初始化之后执行的方法"); return bean; } }
|
1 2 3 4 5 6 7
| <bean id="orders" class="com.atguigu.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod"> <property name="oname" value="手机"></property> </bean>
<bean id="myBeanPost" class="com.atguigu.spring5.bean.MyBeanPost"></bean>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @Test public void testBean3() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml"); Orders orders = context.getBean("orders", Orders.class); System.out.println("第四步 获取创建 bean 实例对象"); System.out.println(orders); context.close(); }
|
(2)按照Spring的格式来写(实现InitializingBean, DisposableBean 接口):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class BookServiceImpl implements BookService, InitializingBean, DisposableBean { private BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public void save() { System.out.println("BookService save ..."); bookDao.save(); } public void destroy() throws Exception { System.out.println("BookService bean 销毁操作 ..."); } public void afterPropertiesSet() throws Exception { System.out.println("BookService bean 初始化操作 ..."); } }
|
1 2 3
| <bean id="service" class="com.test.service.impl.BookServiceImpl"> <property name="bookDao" ref="dao"></property> </bean>
|
1 2 3 4 5 6 7
| public static void main(String[] args) { ClassPathXmlApplicationContext b=new ClassPathXmlApplicationContext("applicationContext.xml"); b.registerShutdownHook(); BookService service =(BookService) b.getBean("service"); service.save(); }
|
4、bean 的后置处理器,bean 生命周期有七步 (正常生命周期为五步,而配置后置处理器后为七步)
(1)通过构造器创建 bean 实例(无参数构造)
(2)为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)
(3)把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization
(4)调用 bean 的初始化的方法(需要进行配置初始化的方法)
(5)把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization
(6)bean 可以使用了(对象获取到了)
(7)当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)
4、IOC 操作 Bean 管理(外部属性文件)
方式一:直接配置数据库信息 :(1)配置Druid(德鲁伊)连接池 (2)引入Druid(德鲁伊)连接池依赖 jar 包
1 2 3 4 5 6 7
| <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/userDb"></property> <property name="username" value="root"></property> <property name="password" value="root"></property> </bean>
|
方式二:引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties 格式文件,写数据库信息(jdbc.properties)
prop.driverClass=com.mysql.jdbc.Driver
prop.url=jdbc:mysql://localhost:3306/userDb
prop.userName=root
prop.password=root
(2)把外部 properties 属性文件引入到 spring 配置文件中 —— 引入 context 名称空间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <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:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${prop.driverClass}"></property> <property name="url" value="${prop.url}"></property> <property name="username" value="${prop.userName}"></property> <property name="password" value="${prop.password}"></property> </bean> </beans>
|
5.自动装配
配置中使用bean标签autowire属性设置自动装配的类型
1 2 3
| <bean id="dao" class="com.test.dao.impl.BookDaoImpl"></bean>
<bean class="com.test.service.impl.BookServiceImpl" id="service" autowire="byType"/>
|
1 2 3 4
| <bean id="dao" class="com.test.dao.impl.BookDaoImpl"></bean> <bean id="dao2" class="com.test.dao.impl.BookDaoImpl"></bean>
<bean class="com.test.service.impl.BookServiceImpl" id="service" autowire="byNmae"/>
|
自动装配使用引用类型依赖注入,不能对简单类型进行操作
使用自动装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
自动装配优先级低于setter注入与构造器注入,同时出现时自动装配失效
6.管理第三方Bean
导入druid的坐标
1 2 3 4 5
| <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.9</version> </dependency>
|
配置数据源对象作为Spring管理的bean
1 2 3 4 5 6 7
| <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/db"/> <property name="username" value="root"/> <property name="password" value="457631"/> </bean>
|
7.加载properties文件
(1)新增context命名空间
1 2 3 4 5
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
修改如下:
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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">
|
(2)使用context空间加载properties文件
1 2 3 4 5
| <context:property-placeholder location="jdbc.properties"/>
<context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>
<context:property-placeholder location="classpath*:*.properties"/>
|
(3)使用属性占位符${}读取properties文件中的属性
1 2 3 4 5 6
| <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource"> <property name="driverClassName" value="${driverClassName}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </bean>
|
总结:
BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
ApplicationContext接口是Spring容器核心接口,初始化bean时立即加载
1 2
| <bean id="dao" class="com.test.dao.impl.BookDaoImpl" lazy-init="true"></bean>
|
ApplicationContext接口提供基础的bean操作相关方法,通过接口扩展其他功能
ApplicationContext接口常用初始类:
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext