大家好,我是被白菜拱的猪。
一个热爱学习废寝忘食头悬梁锥刺股,痴迷于girl的潇洒从容淡然coding handsome boy。
文章目录
一、写在前言
二、IoC Bean管理
(一)FactoryBean
在Spring中有两种类型的bean,一种是普通的bean,一种是工厂bean(FactoryBean)注意这与上一篇讲的BeanFactory不同,BeanFactory是一种容器。
- 普通bean返回类型与配置文件中定义的bean类型一致
- factorybean返回类型与配置文件中定义的bean类型可以不一致
那么如何实现让其返回类型与定义的类型不一致呢?
第一步是创建一个类,让其实现FactoryBean接口
第二步实现接口的方法,在方法中定义要返回的bean类型
package com.codingboy.spring5.factorybean;
import com.codingboy.spring5.bean.Book;
import org.springframework.beans.factory.FactoryBean;
/**
* @author: ljl
* @date: 2020/8/31 13:40
* @description: 定义工厂bean
*/
public class MyBean implements FactoryBean<Book> {
//定义工厂bean的返回类型
public Book getObject() throws Exception {
// String className = "com.codingboy.spring5.bean.Book";
// Book book = (Book) Class.forName(className).newInstance();
Book book = new Book();
return book;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
注意在测试的时候这里不再是MyBean.class,而是Book.class
@Test
public void test() {
ApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");
Book book = context.getBean("myBean", Book.class);
System.out.println(book);
}
(二)Bean的作用域
bean的作用就是指在Spring中,对象的创建是单实例还是多实例。
在Spring中对象的创建默认是单实例的,如图所示,使用Spring容器创建多个对象,他们的地址是一样的,说明他们是同一个对象。
那么多实例是如何实现的呢?
1、scope属性
在bean标签中有一个scope属性,他有两个值,singleton和prototype,默认为singleton即单例,prototype为多例。
<bean id="book" class="com.codingboy.spring5.bean.Book" scope="prototype">
<constructor-arg name="name" value="鹿鼎记"></constructor-arg>
<constructor-arg name="author" value="金庸"></constructor-arg>
</bean>
此时再次测试,他们打印的地址不一样,说明不是同一个对象
2、singleton与prototype的区别
第一个区别就是singleton是单实例,prototype是多实例
第二个区别就是scope属性值为singleton时,对象的创建是在加载配置文件的时候
prototype 是在getBean时创建,这类似于前面讲的BeanFactory与ApplicationContext的区别。
(三)Bean的生命周期
1、生命周期
人的生命周期就是从出生到死亡,而bean的生命周期就是指从bean的创建到bean的销毁
2、具体步骤(五步)
- 通过构造器创建bean实例(无参构造方法)
- 为bean属性设置值和对其他bean的引用(通过set方法)
- 调用bean的初始化方法(这个需要自己配置 在bean标签中使用init-method属性)
- bean的对象就可以使用了
- 当容器销魂时,调用bean的销毁方法(这个同初始化方法一样也需要自己来配置,在bean标签中使用destroy-method属性)
<bean id="person" class="com.codingboy.spring5.bean.Person" init-method="initPerson" destroy-method="destroyPerson"></bean>
3、具体演示
在每一个方法里面写一个输出,然后调用测试,注意这里的close方法是在实现类才有的。
4、bean的后置处理器(七步)
在原先的基础上又在初始化前后各加了一个方法
- 通过构造器创建bean实例(无参构造方法)
- 为bean属性设置值和对其他bean的引用(通过set方法)
- 初始化前,把bean实例传给后置处理器方法
- 调用bean的初始化方法(这个需要自己配置 在bean标签中使用init-method属性)
- 初始化后,把bean实例传给后置处理器方法
- bean的对象就可以使用了
- 当容器销魂时,调用bean的销毁方法(这个同初始化方法一样也需要自己来配置,在bean标签中使用destroy-method属性)
第一步创建一个类然后实现了BeanPostProcessor接口
package com.codingboy.spring5.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.lang.Nullable;
/**
* @author: ljl
* @date: 2020/8/31 21:13
* @description: bean的后置处理器
*/
public class MyPostBean 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;
}
}
第二步在配置文件配置该类,这样每创建一个bean都会交给bean的后置处理器处理一下,假如需要对所有的bean作统一的操作可以使用到后置处理器
(四)自动装配
之前讲的都是手动装配,对每个属性使用property标签对其赋值,而自动装配是根据装配规则(属性名称或者属性类型),对属性注入值,注意这里是属性值,bean标签中有一个属性autowire有两个值byName,byType,即属性名称与属性类型。属性名称对应的变量名与bean的id一致,根据属性类型赋值,假如有一个类型有多个bean的话就会出错。
(五)引入外部属性文件
当我们在bean中写的属性太多,假如日后需要修改的话就会很麻烦,那么我们能不能把这些属性值单独放在一个文件中,然后在bean中引入这个文件,然后去使用这个文件中的值,我可以很负责任的告诉你们可以的。
拿数据库连接池为例
第一步在xml前面什么context空间,就像前面讲的p,util空间
第二步引入外部配置文件jdbc.properties
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
第三步使用配置文件中的属性
三、结束语
讲的都是很基础,再学一遍确实没有查漏补缺了很多,但是还是在敲怎么做,没有讲底层原理,慢慢来吧。在学校的效率还是一如既往的低,明天找个时间写写大三的规划,不能盲目的学啊。之前买的显示屏今天到了,敲代码确实不是一般的爽啊,按理说大学还有两年,但我认为就还有一年,因为大四这个时候就要找工作了,留给自己学习的时间也就一年,希望在大三这一年能够有所收获,码出风采。