前言:

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相关推荐

  1. Spring : Spring定义Bean的两种方式:lt; bean gt;和@Bean

    1.美图 2.概述 Spring中最重要的概念IOC和AOP,实际围绕的就是Bean的生成与使用. 什么叫做Bean呢?我们可以理解成对象,每一个你想交给Spring去托管的对象都可以称之为Bean. ...

  2. spring 注入bean的两种方式

    我们都知道,使用spring框架时,不用再使用new来实例化对象了,直接可以通过spring容器来注入即可. 而注入bean有两种方式: 一种是通过XML来配置的,分别有属性注入.构造函数注入和工厂方 ...

  3. spring配置属性的两种方式

    spring配置属性有两种方式,第一种方式通过context命名空间中的property-placeholder标签 <context:property-placeholder location ...

  4. 定义字符串的两种方式

    定义字符串的两种方式 数组定义 char name[] = "answer" 指针定义 char *name = "answer" 比较 字符数组里的字符可以修 ...

  5. Spring系列教程八: Spring实现事务的两种方式

    2019独角兽企业重金招聘Python工程师标准>>> 一. Spring事务概念: 事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的 ...

  6. c语言向文件中写入字符串_C语言中定义字符串的两种方式及其比较

    先看如下代码: 以上用两种方式定义一个字符串: 1.定义一个char * 类型指针,指向字符串首字符首地址. 2.定义一个数组,数组里存放元素为字符串各个字符+'0',其中'0'为码0值,编译器会自动 ...

  7. Spring依赖注入的两种方式(根据实例详解)

    1,Set注入    2,构造注入 Set方法注入: 原理:通过类的setter方法完成依赖关系的设置 name属性的取值依setter方法名而定,要求这个类里面这个对应的属性必须有setter方法. ...

  8. spring事务管理的两种方式

    一.注解式事务 1.注解式事务在平时的开发中使用的挺多,工作的两个公司中看到很多项目使用了这种方式,下面看看具体的配置demo. 2.事务配置实例 (1).spring+mybatis 事务配置 &l ...

  9. spring---自定义Filter有两种方式

    文章目录 前言 一.基于注解 二.注册bean 前言 在我们开发中经常需要对请求做一些自定义的过滤处理,如最常见的jwt每次请求进来我们都需要去解析判断token这个时候肯定就需要自定义一个filte ...

最新文章

  1. mysql中的cache和buffer_mysql Cache和Buffer区别有哪些?
  2. 【AI不惑境】计算机视觉中注意力机制原理及其模型发展和应用
  3. Redis线上救命丸:01---误操作AOF、RDB恢复数据
  4. 对称加密、非对称加密深度解析
  5. python(条件语句和基本数据类型)
  6. network of emergency contacts---BFS
  7. Eps总结(2)——Eps常用命令与快捷键
  8. 210页的《pandas官方文档中文版》.pdf
  9. 菜刀之中国蚁剑-安装使用及下载地址
  10. 我奋斗了十八年不是为了和你喝一杯咖啡
  11. OpenCV——修改图像像素(随心所欲)
  12. 焦点较中的网络视频相关
  13. 0基础学Java(2)
  14. 用计算机完成下表的视距测量计算公式,2012测量学计算题库及参考答案
  15. VIBE运动目标检测算法实现
  16. 黄山职业技术学院计算机专业怎么样啊,黄山职业技术学院怎么样
  17. Arduino DIY 电子自动浇花浇水系统
  18. Android测试能不能用monk,Android自动化测试-Monkey和MonkeyRunner
  19. Google Earth Engine-06(GEE操作方法)
  20. 大搜车Java面试 2017.10.30

热门文章

  1. vue:vue-video-player(m3u8)视频播放组件Uncaught TypeError: Object(...) is not a function at Module.eval
  2. 安装Velero备份k8s
  3. SpringBoot集成JMH进行基准测试
  4. OpenHarmony/HarmonyOS文本通用属性
  5. 【Marvelous Designer】布料预设汉化+布料模拟流程
  6. Eclipse中格式化JS代码
  7. Python从入门到精通的完整学习路线图(流程图)【附:全套python学习资料】
  8. 【Java】LeetCode 1227. 飞机座位分配概率——数学好一行解决
  9. 制作歌词录入系统php,AJAX_ajax技术制作得在线歌词搜索功能,最新制作完成的在线歌词搜索 - phpStudy...
  10. VDL:唯品会强一致、高可用、高性能分布式日志存储介绍(产品篇)