前言:

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. Eclipse插件:Eclipse Color Theme
  2. 将所有行复制到剪贴板
  3. node.js-session问题
  4. python 怎么得到图像深度图 软件_Python为8bit深度图像应用color map
  5. 变分模态分解 python_Variational Mode Decomposition (变分模态分解)
  6. Visual Basic 基础知识
  7. jovi五子棋下载_五子棋终结者
  8. Python之shp文件
  9. 上海内推 | 上海人工智能实验室招聘计算视觉实习生(NeRF神经渲染方向)
  10. 几种炫酷的Web特效
  11. 服务器的mib文件,snmp 服务器增加 mib
  12. 翟菜花:《完美世界》手游大火,大文娱的卡路里能释放多少热量?
  13. Excel函数SUMIFS和COUNTIFS详解
  14. linux 配置 ftp 服务器以及 ftp 客户端登录
  15. Codeforces Round #717 (Div. 2)(ABCD)
  16. 【SSL】2021-08-19 1045.采药
  17. 网站移动适配之Meta标注、移动跳转实用篇 转载
  18. SONICWALL防火墙 L2TP ×××配置方法
  19. 宋晓丽竟是地产富翁千金 与俊男刘涛地下情多年
  20. NMEA0813协议简介

热门文章

  1. RIP v2 汇总
  2. Hook技术【移动端PC端详解】
  3. “初链”主网上线解析之“初始化”
  4. k8s部署--没到8次就学会了
  5. java利用Freemarker模板生成格式友好的doc或者docx文档
  6. 高中数学;函数定义域秒解技巧(学好函数突破数学)
  7. QT综合大作业—— 多媒体应用程序设计
  8. 安卓移动开发-第一章
  9. fedora20卸载maxthon
  10. Session详解,学习Session,这篇文章就够了(包含底层分析和使用)