Spring5学习笔记——IOC操作之Bean管理(XML实现之二)

IOC操作—Bean管理

基于 xml 配置文件实现

FactoryBean

Spring 有两种类型 bean,一种是普通 bean,另一种是工厂 bean(FactoryBean)

  • 普通 bean:在配置文件中定义的 class 属性值类型就是返回的 bean 类型
  • 工厂 bean:在配置文件定义的 class 属性值类型与返回的 bean 类型可以不一样

工厂 Bean 的实现方式:
(1)创建类,实现 FactoryBean 接口,这个类即为工厂 bean 类
(2)实现接口内的方法,在 getObject() 方法中定义返回的 bean 类型

MyBean.java

package com.mcc.spring5.factoryBean;

import org.springframework.beans.factory.FactoryBean;

public class MyBean implements FactoryBean<OtherBean> {

	@Override
	public OtherBean getObject() throws Exception {
		return new OtherBean();
	}

	@Override
	public Class<OtherBean> getObjectType() {
		return null;
	}

}

OtherBean.java

package com.mcc.spring5.factoryBean;

public class OtherBean {

}

Spring 配置文件 factoryBean.xml

配置文件中配置的是 MyBean 类型的对象,但因为 MyBean 实现了 FactoryBean 接口,因此最后得到的对象是泛型中输入的类型的对象,即 OtherBean 对象

<?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">
	
	<bean id="myBean" class="com.mcc.spring5.factoryBean.MyBean"></bean>

</beans>

测试

package com.mcc.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mcc.spring5.factoryBean.OtherBean;

public class TestFactoryBean {
	@Test
	public void testUserService() {
		ApplicationContext context = new ClassPathXmlApplicationContext("factoryBean.xml");
		OtherBean otherBean = context.getBean("myBean", OtherBean.class);
		System.out.println(otherBean);//com.mcc.spring5.factoryBean.OtherBean@4961f6af
	}
}

Bean 的作用域

  1. 在 Spring 中,可以设置创建的 bean 实例是单实例还是多实例,默认情况下,bean 是单实例对象。
  2. 在配置文件中设置 bean 是单实例还是多实例:
    (1)在对象的 bean 标签中有属性:scope,用于设置单实例还是多实例
    (2)值为:singleton 时,表示是单实例,值为:prototype 时,表示是多实例
<bean id="myBean" class="com.mcc.spring5.factoryBean.MyBean" scope="prototype"></bean>
  1. singleton 与 prototype 的区别:
    (1)singleton:单实例,prototype:多实例
    (2)scope 值为 singleton 时,在加载 spring 配置文件的同时就会创建该单实例对象;
             scope 值为 prototype 时,在调用 getBean() 方法时才会创建该多实例对象。

Bean 的生命周期

完整的生命周期有 7 步:
(1)Bean所在类的构造器方法
(2)调用set()方法注入属性
(3)配置文件初始化之前的操作
       (后置处理器 postProcessBeforeInitialization)
(4)初始化方法
       (在 bean 标签中使用属性:init-method 完成)
(5)配置文件初始化之后的操作
       (后置处理器 postProcessAfterInitialization)
(6)获取Bean实例
       (getBean() 方法)
(7)销毁 Bean 实例方法
       (在 bean 标签中使用属性:destroy-method 完成,在方法内关闭 ApplicationContext 资源时自动调用)

       其中,第(3)(5)步,需要创建一个类,实现 BeanPostProcessor 接口,进而实现接口内的两个方法 postProcessBeforeInitialization()、postProcessAfterInitialization(),实现后置处理器的创建,在 xml 文件中配置该类后,该类就可以供当前 xml 文件中的所有对象使用。

后置处理器类 MyBeanProcess.java

package com.mcc.spring5.life;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanProcess implements BeanPostProcessor{

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("(第五步:)配置文件初始化之后的操作");
		return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("(第三步:)配置文件初始化之前的操作");
		return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
	}
	
}

BeanLife.java

package com.mcc.spring5.life;
/**
 * 演示 Spring 中 Bean 的生命周期
 * @author MCC
 *
 */
public class BeanLife {
	private String name;
	/**
	 * 无参构造器
	 */
	public BeanLife() {
		System.out.println("第一步:Bean所在类的构造器方法");
	}
	
	public String getName() {
		return name;
	}
	/**
	 * set() 方法设置属性值
	 */
	public void setName(String name) {
		System.out.println("第二步:调用set()方法注入属性");
		this.name = name;
	}
	/**
	 * 初始化方法
	 */
	public void init() {
		System.out.println("第三步:初始化方法");
	}
	/**
	 * 销毁 Bean 实例方法
	 */
	public void destory() {
		System.out.println("第五步:销毁 Bean 实例方法");
	}
	@Override
	public String toString() {
		return "BeanLife [name=" + name + "]";
	}
	
}

Spring 配置文件 beanLife.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="beanLife" class="com.mcc.spring5.life.BeanLife" init-method="init" destroy-method="destory">
		<property name="name" value="beanLife"></property>
	</bean>
	
	<!-- 配置 后置处理器,该处理器能够为当前 xml 文件中的所有对象使用 -->
	<bean id="myProcess" class="com.mcc.spring5.life.MyBeanProcess"></bean>
</beans>

测试

@Test
public void testBeanLife() {
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beanLife.xml");
	BeanLife bean = context.getBean("beanLife", BeanLife.class);
	System.out.println("第四步:获取Bean实例");
	System.out.println(bean);
	//调用配置文件中配置的销毁方法时,需要关闭context资源
	context.close();
}

属性的自动装配

1、什么是自动装配?
根据指定的装配规则(属性名称或属性类型),Spring 自动将匹配到的对象作为属性进行注入。

2、实现方法:
在 bean 标签中,通过 autowire 属性实现,当值为:
(1)byName:根据名称进行查找,当属性名与 bean 标签的 id 值相同时,该对象被注入。
(2)byType:根据类型进行查找,当类型与 bean 标签的 class 类型相同时,该对象被注入,注意,若有多个相同类型的对象,则会注入失败。

Emp.java

package com.mcc.spring5.autowire;

public class Emp {
	private String name;
	private Dept dept;

	public Dept getDept() {
		return dept;
	}
	public void setDept(Dept dept) {
		this.dept = dept;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Emp [name=" + name + ", dept=" + dept + "]";
	}
	
}

Dept.java

package com.mcc.spring5.autowire;

public class Dept {
	@Override
	public String toString() {
		return "Dept []";
	}
}

Spring 配置文件 autowire.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!--
		实现自动装配:
		bean 标签的属性 autowire, 实现自动装配
		autowire 属性的常用值:
			byName:根据属性名称注入,要注入的属性值(Dept dept)与被注入对象的 id 值(dept)要相同,才能注入成功
			byType:根据属性类型注入
	-->
	<bean id="emp" class="com.mcc.spring5.autowire.Emp" autowire="byName">
	<!-- byType 相同,查找类为 Dept 的对象,进行注入,不再演示 -->
		<property name="name" value="emp01"></property>
	</bean>
	
	<bean id="dept" class="com.mcc.spring5.autowire.Dept"></bean>
</beans>

测试

@Test
public void testAutowire() {
	ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("autowire.xml");
	Emp emp = context.getBean("emp", Emp.class);
	System.out.println(emp.toString());//Emp [name=emp01, dept=Dept []]
}

引入外部属性文件

以 druid 数据库连接池为例,演示通过引入外部属性文件的方式,创建数据库连接池对象。

实现步骤:
(1)引入 druid 数据库连接池的 jar 包。
(2)创建 druid 配置文件:druid.property
在这里插入图片描述
(3)在 spring 配置文件中引入 context 名称空间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"

(4)在 spring 配置文件中通过 <context:property-placeholder/>标签引入外部属性文件,该标签的 location 属性可以指定外部文件所在的位置。

<!-- classpath: 表示文件在 src 文件夹下 -->
<context:property-placeholder location="classpath:druid.property"/>

(5)创建 druid 对象,并通过 ${} 表达式,引入对应的值。

<!-- 配置 druid 对象 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
	<property name="driverClassName" value="${druid.driverClassName}"></property>
	<property name="url" value="${druid.url}"></property>
	<property name="username" value="${druid.username}"></property>
	<property name="password" value="${druid.password}"></property>
</bean>

druidOutterFile.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">
	
	<!-- classpath: 表示文件在 src 文件夹下 -->
	<context:property-placeholder location="classpath:druid.property"/>
	
	<!-- 配置 druid 对象 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="driverClassName" value="${druid.driverClassName}"></property>
		<property name="url" value="${druid.url}"></property>
		<property name="username" value="${druid.userName}"></property>
		<property name="password" value="${druid.password}"></property>
	</bean>
	
</beans>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值