《Spring使用到源码理解》第二章:Bean标签使用

1. 什么是Bean标签

其实在上一章我们已经使用Bean标签,它就是标识那些对象需要交给Spring容器管理,以及设置Bean的相关属性。

2. 带着疑问阅读

  • bean标签如何使用?
  • bean标签是如何加载的?
  • bean标签有那些属性?
  • 什么是懒加载?
  • bean标签在容器中体现的形式是什么?

3.基础使用

要学习新的一个知识点,我们第一步需要先让其先跑起来,我再来研究它的属性
创建一个spring管理的bean

public class UserService{
	public String getName(){
		return "张三";
	}
}

创建一个application.xml(名字无所是什么)文件,并且将其放在resource目录下

<?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
		https://www.springframework.org/schema/beans/spring-beans.xsd">
		<bean id="userService" class="com.qiupeng.bean.ioc.service.UserService"/>
</beans>

创建一个测试类

public class BeanTest(){
	public static void main(String[] arg){
		ApplicationContext = context = new ClassPathXmlApplicationContext("classpath:application.xml");
		UserService userService = context.getBean("userService",UserService.class);
		System.out.printfln(userService.getName());
	}
}

最终输出

张三

通过上述代码,以及使用了最简化Bean标签,将对象交给了容器进行管理了。

3. Bean标签属性使用和说明

属性说明
id当前bean在容器中的唯一标识,该值不允许重复,建议使用类名首字母小写进行设置,比如类名是UserService那么id就设置为userService
class设置需要管理bean的class全路径
scope当前实例化bean的作用域
constructor-arg设置有参构造函数的注入参数
properties通过set方法进行属性注入
autowire属性自动注入方式
lazy-init是否为懒加载bean
init-methodbean初始化掉调用
destroy-methodbean销毁时调用

bean标签中大体可以分为两类,bean基础配置和bean的属性注入,本章中我们先了解一下bean基础配置的属性。

3.1. id

该属性在第一个例子以及进行了演示,就是给注入的bean设置一个ID属性,并且该id不允许重复,在使用ApplicationContext可以通过该Id属性进行获取bean.

3.2. class

该属性在第一个例子以及进行了演示,该属性就是设置当前bean的class全路径,Spring通过该属性进行构建bean对象。

3.3. scope

该属性时标识bean的作用域,默认设置的是singleton代表是单例的意思,该属性还可以设置为prototyperequestsessionapplicationwebsocket,其中常用的就是singletonprototype(多例模式)。
创建两个java类

 public class PrototypeModel{
 }
public class SingletonModel{
}

修改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
 	https://www.springframework.org/schema/beans/spring-beans.xsd">
 		<!-- 单例的bean -->
 		<bean id="singletonModel" class="com.qiupeng.bean.ioc.model.SingletonModel"/>
 		<!-- 多例的bean -->
 		<bean id="prototypeModel" class="com.qiupeng.bean.ioc.model.PrototypeModel" scope="prototype" />
 </beans>

创建一个测试类

public class BeanIocTest {
 public static void main(String[] arg) {
 	ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
 	for (int i = 0; i < 10; i++) {
 		PrototypeModel prototypeModel = context.getBean("prototypeModel", PrototypeModel.class);
 		SingletonModel singletonModel = context.getBean("singletonModel", SingletonModel.class);
 		System.out.println("prototypeModel:" + prototypeModel);
 		System.out.println("singletonModel:" + singletonModel);
 		System.out.println("-----------------------------------------");

 	}
 }
}

最终输出

prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@58be6e8
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@3f9342d4
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@ab7395e
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@50d13246
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@2bd08376
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@e70f13a
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@3d3e5463
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@64a40280
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@4b40f651
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------
prototypeModel:com.qiupeng.bean.ioc.model.PrototypeModel@42b02722
singletonModel:com.qiupeng.bean.ioc.model.SingletonModel@7331196b
-----------------------------------------

观察输出结果可以看出,单例对象每次获取的都是获取的是同一个对象,而多例模式每次获取到的不通的对象。

3.4. lazy-init

该属性默认为false,而且该属性只有标识单例模式的对象才会有效果,因为多例对象在初始化容器后是不会创建(后面源码理解章节会进步介绍)。
为了测试懒加载,创建一个懒加载的类

	public class LazyModel{
	}

修改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
		https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 单例的bean -->
	<bean id="singletonModel" class="com.qiupeng.bean.ioc.model.SingletonModel"/>
	<!-- 多例的bean -->
	<bean id="prototypeModel" class="com.qiupeng.bean.ioc.model.PrototypeModel" scope="prototype" />
	<!-- 懒加载 -->
	<bean id="lazyModel" class="com.qiupeng.bean.ioc.model.LazyModel" lazy-init="true" />
</beans>

修测试类

public class BeanIocTest {
	public static void main(String[] arg) {

		ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
		for (int i = 0; i < 10; i++) {
			PrototypeModel prototypeModel = context.getBean("prototypeModel", PrototypeModel.class);
			SingletonModel singletonModel = context.getBean("singletonModel", SingletonModel.class);
			System.out.println("prototypeModel:" + prototypeModel);
			System.out.println("singletonModel:" + singletonModel);
			System.out.println("-----------------------------------------");

		}
	}
}

通过debug方式来查看容器存在那些bean对象。
在这里插入图片描述
通过上图可以看见在容器创建完成后,注入的bean对象只有SingletonModel生效了,其他两个都没有生效,说明在容器创建完成后,懒加载和多例的bean对象都是没有被创建的。
在这里插入图片描述
将代码执行过getBean后,发现容器中已经存在了LazyModel这个对象,所有我们可以下结论为,懒加载对象在我们需要使用的时候才会被创建。

3.5. init-method

该数据设置一个函数名称,在bean对象创建时会自动调用该函数。
添加前置函数
SingletonModel类中添加一个init的函数(名称可以随便取)。

	public void init() {
		System.out.println("调用singletonModel的init函数");
	}

修改application.xml
修改xml,在bean的标签中添加init-method的属性,并且设置为init

<bean id="singletonModel" class="com.qiupeng.bean.ioc.model.SingletonModel" init-method="init" />

测试结果
运行测试函数,通过查看日志可以发现输出了调用singletonModel的init函数

调用singletonModel的init函数

3.6. destroy-method

destroy-method和init-method编写方式一样的,这里就不进行演示了。但是destroy-method函数调用是在bean销毁的时候触发

4.总结

  • 使用< bean>标签就是能实现bean注入。
  • bean标签加载流程,xml=>XmlBeanDefinitionReader=>BeanDefinition =>ApplicationContext=>bean.
  • 该文章第3节已经说明了。
  • 懒加载是在使用的时候,懒加载只针对单例模式有效。
  • bean标签通过XmlBeanDefinitionReader读取后转换成BeanDefinition ,在存入ApplicationContext中。

5.扩展知识

大家可以思考一个问题,当前我们都是把所有bean标签写到一个配置文件中,如果很多bean标签就会导致这个文件很臃肿,其实spring也提供import标签来进行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
		https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 加载外部文件 -->
	<import resource="application-dev.xml"/>
</beans>

通过上述例子,就可以使用一个xml来管理所有xml文件,这样就可以分模块来管理xml了。(其实bean标签没有必要这么复杂,后面文章也会介绍扫描方式来扫描bean对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值