上节介绍了注入各种类型属性的方式,本节将还是基于xml方式实现自动装配,引入外部文件
FactoryBean
在之前学习的bean标签都是只能返回class属性中类型的类,当使用了FactoryBean之后就可以自定义返回类型
BeanFactory和FactoryBean不同,BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
演示:
代码还是使用之前的代码新建一个类需要实现FactoryBean
public class BookFactory implements FactoryBean<Book> {
@Override
public Book getObject() throws Exception {
Book book = new Book();
return book;
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
并且在配置文件中将该类创建
<bean class="life.wangquanguo.spring5.FactoryBean.BookFactory" id="bookFactory"> </bean>
可以通过该bean直接获取到Book对象
Bean作用域
在 Spring 里面,默认情况下,bean 是单实例对象
在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
singleton,表示是单实例对象
prototype,表示是多实例对象
singleton 和 prototype 区别
singleton 单实例,prototype 多实例
设置 scope 值是 singleton 时候,加载 spring 配置文件时候就会创建单实例对象
设置 scope 值是 prototype 时候,不是在加载 spring 配置文件时候创建 对象,在调用getBean 方法时候创建多实例对象
Bean生命周期
- 通过无参构造方法创建对象
- 通过set方法注入属性
- (如果有后置处理器)把bean对象传递给后置处理器处理
- 调用初始化方法(如果存在初始化方法,需要在bean标签中单独配置)
- (如果有后置处理器)把bean对象传递给后置处理器处理
- bean对象正常被使用
- 容器关闭时,调用销毁方法(如果存在销毁方法,需要在bean标签中配置)
其中后置处理器需要编写类实现BeanPostProcessor并实现两个方法
public class BookPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("后置处理器前置方法");
return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("后置处理器后置方法");
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
}
spring会将bean对象在初始化方法前后分别传递给前置方法和后置方法处理
<bean class="life.wangquanguo.spring5.beanPost.BookPost" id="bookPost"></bean>
并且配置文件中所有bean都会经过后置处理器
初始化方法和销毁方法需要在bean标签中通过init-method和destroy-method两个属性来配置
<bean id="beanLifeClass" class="life.wangquanguo.spring5.BeanLiftClass" init-method="initMethod" destroy-method="destoryMethod">
<property name="name" value="123"></property>
</bean>
演示:
准备一个类展示生命周期
public class BeanLiftClass {
public BeanLiftClass() {
System.out.println("构造方法");
}
private String name;
public void setName(String name) {
this.name = name;
System.out.println("set方法");
}
public void initMethod(){
System.out.println("初始化方法");
}
public void destoryMethod(){
System.out.println("销毁方法");
}
public void useMethod(){
System.out.println("正常使用的方法");
}
}
测试类
//生命周期测试
@Test
public void test5(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
BeanLiftClass book = context.getBean("beanLifeClass", BeanLiftClass.class);
book.useMethod();
//关闭容器
((ClassPathXmlApplicationContext)context).close();
}
运行结果为
构造方法
set方法
后置处理器前置方法
初始化方法
后置处理器后置方法
后置处理器前置方法
后置处理器后置方法
正常使用的方法
自动装配
之前都是使用ref或者property标签进行对象属性的装配,通过自动装配可以根据指定装配规则(属性名称或者属性类型),Spring 自动将匹配的属性值进行注入
<bean id="book" class="life.wangquanguo.spring5.Book" autowire="byType"></bean>
<bean id="pen1" class="life.wangquanguo.spring5.Pen"></bean>
通过autowire属性就可以不需要ref或者property标签注入属性,其中autowire有两个选项
byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样
byType 根据属性类型注
引入外部配置文件
如果spring配置文件中bean很多,将对象中的属性放在spring配置文件中,将不利于维护项目和更改配置,所以spring可以引入外部配置文件
首先需要引入命名空间
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
以Druid连接池为例
使用context:property-placeholder标签将外部文件引入进来
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${pool.url}" />
<property name="driverClassName" value="${pool.driverClass}" />
<property name="username" value="${pool.userName}" />
<property name="password" value="${pool.password}" />
</bean>
<!--引入配置文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
使用${}引入外部文件中的值
创建jdbc.properties文件
pool.url = jdbc:mysql://localhost:3306/user
pool.driverClass = com.mysql.jdbc.Driver
pool.userName = root
pool.password = root
编写测试类
//外部引用
@Test
public void test7(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
DruidDataSource dataSource = context.getBean("dataSource", DruidDataSource.class);
System.out.println(dataSource.getUrl());
System.out.println(dataSource.getDriverClassName());
System.out.println(dataSource.getUsername());
System.out.println(dataSource.getPassword());
}
打印结果
jdbc:mysql://localhost:3306/user
com.mysql.jdbc.Driver
root
root
Q.E.D.
Comments | 0 条评论