Spring定义Bean的两种方式:<bean>和@Bean
前言:
Spring中最重要的概念IOC和AOP,实际围绕的就是Bean的生成与使用。
什么叫做Bean呢?我们可以理解成对象,每一个你想交给Spring去托管的对象都可以称之为Bean。
今天通过Spring官方文档来了解下,如何生成bean,如何使用呢?
1.通过XML的方式来生成一个bean
最简单也是最原始的一种方式,通过XML来定义一个bean,我们来看下其过程
1)创建entity,命名为Student
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student implements Serializable {private static final long serialVersionUID = -2088281526481179972L;private int id;private String name;private int age;
}
2)在beans.xml中定义Student
<!-- 1.空值的student --><bean id="studentNoValue" class="domain.Student"/><!-- 2.带值的student --><bean id="student" class="domain.Student"><property name="id" value="11"/><property name="age" value="22"/><property name="name" value="jack"/></bean><!-- 3.全参构造:使用成员变量名称对应 --><bean id="studentConstruct" class="domain.Student"><constructor-arg name="age" value="22"></constructor-arg><constructor-arg name="id" value="11"></constructor-arg><constructor-arg name="name" value="jack"></constructor-arg></bean><!-- 4.全参构造:使用成员变量index对应 --><bean id="studentConstruct2" class="domain.Student"><constructor-arg index="0" value="11"></constructor-arg><constructor-arg index="1" value="jack"></constructor-arg><constructor-arg index="2" value="22"></constructor-arg></bean><!-- 5.全参构造:使用成员变量类型对应 --><bean id="studentConstruct3" class="domain.Student"><constructor-arg type="int" value="11"></constructor-arg><constructor-arg type="java.lang.String" value="jack"></constructor-arg><constructor-arg type="int" value="22"></constructor-arg></bean>
总结:可以看到,创建bean的方式多种多样,我们可以通过属性来赋值<property>,也可以通过构造参数来赋值<constructor>,关于构造赋值以上展示了三种方式,我们可以根据自己的需求来选择对应的方式。
3)测试bean
public class ApplicationContextTest {@Testpublic void testXml(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");Student studentNoValue = (Student) applicationContext.getBean("studentNoValue");Student studentFullValue = (Student) applicationContext.getBean("studentFullValue");System.out.println(studentNoValue);System.out.println(studentFullValue);Student studentConstruct1 = (Student) applicationContext.getBean("studentConstruct");Student studentConstruct2 = (Student) applicationContext.getBean("studentConstruct2");Student studentConstruct3 = (Student) applicationContext.getBean("studentConstruct3");System.out.println(studentConstruct1);System.out.println(studentConstruct2);System.out.println(studentConstruct3);Book bookChinese = (Book) applicationContext.getBean("bookChinese");System.out.println(bookChinese);}
}
// res:
Student(id=0, name=null, age=0)
Student(id=11, name=jack, age=22)
Student(id=11, name=jack, age=22)
Student(id=11, name=jack, age=22)
Student(id=11, name=jack, age=22)
2.<bean>标签深入了解
我们刚才介绍了最基本的Bean使用方式,大家会发现<bean>标签还有其他的属性,比如name/scope/lazy-init/init-method/...等,这些是做什么用的呢?我们在实际的工作中怎么使用呢?
1)name属性
在介绍name属性之前,我们先来看下ApplicationContext.getBean()的两种方式
* ApplicationContext.getBean(String name)
* ApplicationContext.getBean(Class<T> requiredType)
第一种方式的这个name是什么呢?我们应该如何定义,又该如何使用呢?
// 上文示例中,我们只是指定了Bean的id和class,如下所示
<bean id="studentNoValue" class="domain.Student" />// 具体获取bean的方式如下:
Student studentNoValue = (Student) applicationContext.getBean("studentNoValue");// 可以看到,在没有指定bean的name属性的时候,默认使用id来获取bean,当做name使用
// 如果我们不想根据id获取,那就需要主动指定bean的name属性,如下所示:
<bean id="studentNoValue" class="domain.Student" name="stuName"/>
// 这样在获取的时候,就需要使用指定的名称来获取,再根据id来获取的时候就会报错了
Student studentNoValue = (Student) applicationContext.getBean("stuName");
* 根据Class来获取这种方式很好理解,这个不关心你定义的id或者name是什么,使用如下:
Student studentNoValue = (Student) applicationContext.getBean(Student.class);
2)scope属性
可以看到,在使用scope属性的时候,提示有两种输入值,分别是singleton/prototype
这个就代表了Spring-Bean的两种创建模式,单例模式和原型模式
* Spring默认使用单例模式来创建Bean,通过ApplicationContext所获得的bean都是同一个bean(在beanName相同的情况下),我们可以来验证下
Student studentNoValue = (Student) applicationContext.getBean("stuName");
Student studentNoValue2 = (Student) applicationContext.getBean("stuName");System.out.println(studentNoValue == studentNoValue2);// true
可以看到的是结果输入为true,从工厂类中两次获取的stuName是同一个对象。
* 下面来验证下原型模式
原型模式:每次获取的bean都为一个新的对象
// 修改beans.xml中studentNoValue的scope为prototype
<bean id="studentNoValue" class="domain.Student" name="stuName" scope="prototype"/>// 然后执行上面的测试代码
Student studentNoValue = (Student) applicationContext.getBean("stuName");
Student studentNoValue2 = (Student) applicationContext.getBean("stuName");System.out.println(studentNoValue == studentNoValue2);// false
可以看到,输出结果为false,原型模式下从工厂类两次获取的stuName不是同一个对象。
3)init-method和destroy-method方法
见名知意,init-method应该是初始化方法的意思,destroy-method应该是销毁方法的意思。那怎么使用呢?
// 在Student.java中添加init()方法和destroy()方法
public void init(){System.out.println("student init...");
}public void destroy(){System.out.println("student destroy...");
}// 在beans.xml中studentNoValue的bean上添加 init-method和destroy-method
<bean id="studentNoValue" class="domain.Student" name="stuName" init-method="init" destroy-method="destroy"/>// 测试方法如下:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Student studentNoValue = (Student) applicationContext.getBean("stuName");applicationContext.close();// 执行结果:
student init...
student destroy...
总结:在获取bean的时候init()方法被执行,在容器被销毁的时候,执行了destroy()方法
根据这个,我们可以在初始化bean和销毁bean的时候做点什么,比如关闭连接,保存记录之类的操作。
延伸:那么初始化init()方法在构造方法之前调用,还是之后调用呢?读者可以自行验证下
总结:还有一些其他属性,笔者就不再一一验证了,下面说一下通过JavaConfig的方法来实现bean的定义。
3.JavaConfig方式的bean定义
JavaConfig是Spring4.x推荐的配置方式,可以完全替代XML的方式定义。
1)如何定义一个Bean
// 创建一个类,命名为SpringConfiguration
@Configuration
public class SpringConfiguration {@Beanpublic Student student(){return new Student(11,"jack",22);}
}// 使用bean
AnnotationConfigApplicationContext applicationContext= new AnnotationConfigApplicationContext(SpringConfiguration.class);
Student student = (Student) applicationContext.getBean("student")
System.out.println(student);// res:
Student(id=11, name=jack, age=22)
相对于XML的使用方式而言,JavaConfig的使用方式基本是同步的
* @Configuration等同于<beans></beans>
* @Bean等同于<bean></bean>
* 通过AnnotationConfigApplicationContext来加载JavaConfig
* 方法名student()就等同于<bean>中的id,默认方法名就是beanName
2)@Bean的其他参数
* name属性等同于<bean>的name
* initMethod属性等同于<bean>的init-method
* destroyMethod属性等同于<bean>的destroy-method
* scope这个比较奇怪,不属于@Bean的参数,这是一个单独的注解,使用方式如下
@Bean(name = "stu",autowire = Autowire.BY_TYPE)
@Scope(value = "singleton")
public Student student(){return new Student(11,"jack",22);
}
总结:
以上全文,我们通过两种方式来定义一个Bean,默认推荐JavaConfig。
还有一些其他属性,笔者就不一一列举了。
参考:
Spring Framework Reference Documentation
代码地址:GitHub - kldwz/springstudy
Spring定义Bean的两种方式:<bean>和@Bean相关推荐
- Spring : Spring定义Bean的两种方式:lt; bean gt;和@Bean
1.美图 2.概述 Spring中最重要的概念IOC和AOP,实际围绕的就是Bean的生成与使用. 什么叫做Bean呢?我们可以理解成对象,每一个你想交给Spring去托管的对象都可以称之为Bean. ...
- spring 注入bean的两种方式
我们都知道,使用spring框架时,不用再使用new来实例化对象了,直接可以通过spring容器来注入即可. 而注入bean有两种方式: 一种是通过XML来配置的,分别有属性注入.构造函数注入和工厂方 ...
- spring配置属性的两种方式
spring配置属性有两种方式,第一种方式通过context命名空间中的property-placeholder标签 <context:property-placeholder location ...
- 定义字符串的两种方式
定义字符串的两种方式 数组定义 char name[] = "answer" 指针定义 char *name = "answer" 比较 字符数组里的字符可以修 ...
- Spring系列教程八: Spring实现事务的两种方式
2019独角兽企业重金招聘Python工程师标准>>> 一. Spring事务概念: 事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的 ...
- c语言向文件中写入字符串_C语言中定义字符串的两种方式及其比较
先看如下代码: 以上用两种方式定义一个字符串: 1.定义一个char * 类型指针,指向字符串首字符首地址. 2.定义一个数组,数组里存放元素为字符串各个字符+'0',其中'0'为码0值,编译器会自动 ...
- Spring依赖注入的两种方式(根据实例详解)
1,Set注入 2,构造注入 Set方法注入: 原理:通过类的setter方法完成依赖关系的设置 name属性的取值依setter方法名而定,要求这个类里面这个对应的属性必须有setter方法. ...
- spring事务管理的两种方式
一.注解式事务 1.注解式事务在平时的开发中使用的挺多,工作的两个公司中看到很多项目使用了这种方式,下面看看具体的配置demo. 2.事务配置实例 (1).spring+mybatis 事务配置 &l ...
- spring---自定义Filter有两种方式
文章目录 前言 一.基于注解 二.注册bean 前言 在我们开发中经常需要对请求做一些自定义的过滤处理,如最常见的jwt每次请求进来我们都需要去解析判断token这个时候肯定就需要自定义一个filte ...
最新文章
- mysql中的cache和buffer_mysql Cache和Buffer区别有哪些?
- 【AI不惑境】计算机视觉中注意力机制原理及其模型发展和应用
- Redis线上救命丸:01---误操作AOF、RDB恢复数据
- 对称加密、非对称加密深度解析
- python(条件语句和基本数据类型)
- network of emergency contacts---BFS
- Eps总结(2)——Eps常用命令与快捷键
- 210页的《pandas官方文档中文版》.pdf
- 菜刀之中国蚁剑-安装使用及下载地址
- 我奋斗了十八年不是为了和你喝一杯咖啡
- OpenCV——修改图像像素(随心所欲)
- 焦点较中的网络视频相关
- 0基础学Java(2)
- 用计算机完成下表的视距测量计算公式,2012测量学计算题库及参考答案
- VIBE运动目标检测算法实现
- 黄山职业技术学院计算机专业怎么样啊,黄山职业技术学院怎么样
- Arduino DIY 电子自动浇花浇水系统
- Android测试能不能用monk,Android自动化测试-Monkey和MonkeyRunner
- Google Earth Engine-06(GEE操作方法)
- 大搜车Java面试 2017.10.30
热门文章
- vue:vue-video-player(m3u8)视频播放组件Uncaught TypeError: Object(...) is not a function at Module.eval
- 安装Velero备份k8s
- SpringBoot集成JMH进行基准测试
- OpenHarmony/HarmonyOS文本通用属性
- 【Marvelous Designer】布料预设汉化+布料模拟流程
- Eclipse中格式化JS代码
- Python从入门到精通的完整学习路线图(流程图)【附:全套python学习资料】
- 【Java】LeetCode 1227. 飞机座位分配概率——数学好一行解决
- 制作歌词录入系统php,AJAX_ajax技术制作得在线歌词搜索功能,最新制作完成的在线歌词搜索 - phpStudy...
- VDL:唯品会强一致、高可用、高性能分布式日志存储介绍(产品篇)