Spring5学习笔记(二)bean实例化(静态工厂、实例工厂)、作用域、生命周期、后置处理器。。。
1、Spring Bean作用域
- prototype: 多实例的
- singleton: 单实例的(默认)
- request:在web环境下,同一次请求创建一个Bean实例(没用)
- session:在web环境下,同一次会话创建一个Bean实例(没用)
1.1、单实例
//xml
<bean id="person" class="com.dong.Person" scope="singleton">
</bean>
@Test
public void test03() {
System.out.println("容器启动完成。。。");
Object bean = ioc.getBean("person");
Object bean1 = ioc.getBean("person");
System.out.println(bean == bean1);
}
总结:
1.在容器启动完成之前就已经创建好了对象,保存在容器中。
2.任何获取都是获取之前创建好的那个对象。
1.2、多实例
//xml
<bean id="person" class="com.dong.Person" scope="prototype">
</bean>
@Test
public void test03() {
System.out.println("容器启动完成。。。");
Object bean = ioc.getBean("person");
Object bean1 = ioc.getBean("person");
System.out.println(bean == bean1);
}
总结:
1.容器启动默认不会创建多实例bean。
2.获取的时候会创建这个bean。
3.每次获取都会创建一个新的对象。
2、Spring Bean的实例化(FactoryBean)重点
创建Book类
public class Book {
private String name;
private Integer price;
private String authorName;
//省略。。。。。
}
2.1、静态工厂方式实例化
创建静态工厂
public class BookStaticFactory {
//静态工厂
//调用方法:对象 = 工程类.工厂方法名();
public static Book getBook(String name) {
System.out.println("BookStaticFactory 书籍");
Book book = new Book();
book.setName(name);
book.setAuthorName("小明");
book.setPrice(100);
return book;
}
}
测试
<!-- 静态工厂(不需要创建工厂本身)factory-method="getBook":指定哪个方法是工厂方法 -->
<!--
class:指定静态工厂全类名
factory-method:指定工厂方法
constructor-arg:可以为方法传参
-->
<bean id="book1" class="com.dong.factory.BookStaticFactory" factory-method="getBook">
<!-- 为方法指定参数 -->
<constructor-arg value="王五"></constructor-arg>
</bean>
@Test
public void test03() {
System.out.println("容器启动完成。。。");
Object bean1 = ioc.getBean("book1");
System.out.println(bean1);
}
2.2、实例工厂方式实例化
创建实例工厂
public class BookInstanceFactory {
//实例工厂
/**
* 工厂本身需要创建对象:
* 工厂类对象 = new 工厂类();
* 工厂类对象.getBook("张三");
* @param name
* @return
*/
public Book getBook(String name) {
System.out.println("BookInstanceFactory书籍");
Book book = new Book();
book.setName(name);
book.setAuthorName("小花");
book.setPrice(200);
return book;
}
}
<!--
1.先配置出示例工程对象
2.配置我们要创建的Book使用哪个工厂实例
factory-bean:指定使用哪个工厂实例
factory-method:使用哪个工厂方法
-->
<bean id="bookInstanceFactory" class="com.dong.factory.BookInstanceFactory"></bean>
<beanid="book2" class="com.dong.Book" factory-bean="bookInstanceFactory"
factory-method="getBook">
<constructor-arg value="赵六"></constructor-arg>
</bean>
@Test
public void test03() {
System.out.println("容器启动完成。。。");
Object bean1 = ioc.getBean("book2");
System.out.println(bean1);
}
2.3、实现FactoryBean工厂方式实例化
创建MyFactoryBeanImpl类实现FactoryBean接口
/**
* 实现了FactoryBean接口的类是Spring可以认识的工厂类;
* Spring会自动地调用工厂方法创建实例
*/
public class MyFactoryBeanImpl implements FactoryBean<Book>{
/**
* getObject:工厂方法
* 返回创建的对象
*/
@Override
public Book getObject() throws Exception {
Book book = new Book();
book.setName(UUID.randomUUID().toString());
return book;
}
/**
* 返回创建的对象的类型
* Spring会自动调用这个方法来确认创建的对象是什么类型
*/
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Book.class;
}
/**
* isSingleton:是否是单例
* false:不是
* true:是
*/
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
}
<!-- FactoryBean(是Spring地一个接口)
只要是这个接口的实现类,Spring都认为是一个工厂
-->
<bean id="myFactoryBeanImpl" class="com.dong.factory.MyFactoryBeanImpl">
</bean>
@Test
public void test03() {
System.out.println("MyFactoryBeanImpl创建对象。。");
Object bean1 = ioc.getBean("myFactoryBeanImpl");
System.out.println(bean1);
}
总结:
1、ioc容器启动的时候不会创建实例。
2、FactoryBean:获取的时候才会创建对象。
3、Spring Bean的生命周期
public class Book {
private String name;
private int price;
private String authorName;
//初始化方法和销毁方法不要有参数
public void myInit() {
System.out.println("图书初始化方法。。。");
}
public void myDestory() {
System.out.println("图书销毁方法。。。");
}
//省略。。。。
}
3.1、单实例bean生命周期
<bean id="book01" init-method="myInit" destroy-method="myDestory" class="com.dong.Book">
</bean>
@Test
public void test() {
Object bean = ioc.getBean("book01");
System.out.println("容器关闭了。。。。");
ioc.close();
}
3.2、多实例bean生命周期
<bean scope="prototype" id="book01" init-method="myInit" destroy-method="myDestory" class="com.dong.Book">
</bean>
@Test
public void test() {
Object bean = ioc.getBean("book01");
System.out.println("容器关闭了。。。。");
ioc.close();
}
总结:
1. 单实例bean,容器启动的时候就会创建好,容器关闭也会销毁创建的bean。
(容器启动)构造器---->初始化方法---->(容器关闭)销毁方法
2. 多实例bean,获取的时候才创建。
获取bean(构造器---->初始化方法)---->容器关闭不会调用bean的销毁方法
3. init-method:初始化方法;destroy-method:销毁方法。
4、Spring Bean的后置处理器
bean后置处理器: BeanPostProcessor(接口)
流程:
(容器启动)构造器---->后置处理器before---->初始化方法----->后置处理器after。。。------->初始化完成
创建MyBeanPostProcessor 实现BeanPostProcessor接口
注意:需要导入Spring-beans的源码包
/**
* 1、编写后置处理器的实现类
* 2、将后置处理器注册在配置文件中
*/
public class MyBeanPostProcessor implements BeanPostProcessor{
/**
* postProcessBeforeInitialization: 初始化之前调用
*
* Object bean 将要初始化的bean
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..."+"bean将要调用初始化方法了,这个bean是:"+bean);
return bean;
}
/**
* postProcessAfterInitialization: 初始化之后调用
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+"bean初始化完了,这个bean是:"+bean);
//初始化之后返回的bean是什么,容器就保存的是什么
return bean;
}
}
<!-- 后置处理器:可以在bean的初始化前后调用方法 -->
<bean id="beanPostProcessor" class="com.dong.MyBeanPostProcessor">
</bean>
@Test
public void test() {
Object bean = ioc.getBean("book01");
System.out.println("容器关闭了。。。。"+bean);
}
总结:
1. 无论bean是否有初始化方法:后置处理器都会默认其有,还会继续工作。
觉得写的不错的小伙伴,可以点赞关注和收藏哦,博主会持续发布与大家共同学习!
- 点赞
- 收藏
- 关注作者
评论(0)