京东自营 618 + 国补 iPhone 历史最低价          领 618 红包,最高25618元

理解 Spring 框架中的 Bean

Spring Bean的概念


首先,Bean这个概念不是Spring独有的。或者说,在Spring成为事实上的JavaEE标准的今天,Java其实存在两套Bean规范。

  • Java Bean
  • Spring Bean

所谓Java Bean,远在天边近在眼前,我们每天都在和它打交道。

Java Bean 是一种符合特定规范的 Java 类,主要用于封装数据。它通常具有以下特征:

  • 私有属性
  • 公有的无参构造函数
  • getter 和 setter 方法

没错,就是这货:

至于Spring Bean,你可以简单地理解为“由Spring 创建、管理、维护的 Java Bean”。Spring Bean 不一定符合 Java Bean 的所有规范,但它们的生命周期和依赖关系由 Spring 容器管理。

想象一下,现在你公司的项目里就存在两种Bean:UserDO和UserService。

不要去纠结它为什么叫Spring Bean,应该问问自己:为什么需要Spring Bean?

俗话说得好,生儿容易养儿难,一个Java Bean就像一个孩子,不是说new完就结束了,你要养它(维护)。new只是最开始、也是最简单的事,麻烦才刚刚开始。

主要维护什么呢?

IOC

Spring最重要的不是存储了什么(What),而是怎么存储的(How),为什么这么存储(Why)。这就引出了一个根本问题:上古程序员为什么要搓出一个Spring?

本质是还是为了解决对象创建和依赖问题。

先说依赖问题。你想象中的依赖应该是很简单的:

但实际的依赖可能是这样的:

当A依赖B时,很自然地需要创建一个B。但是B的创建又依赖C、D,而C又依赖E、F。如果没有Spring帮你搞定这层依赖关系,你可能需要在A的代码里写一坨代码,仅仅是为了得到B。

那么,Spring是如何搞定A的创建的呢?依赖注入。很简单,我先尝试创建A,结果发现A依赖B,那么就去创建B,结果发现B又依赖C和D...一路递归下去,直到创建E、F结束,再递归回来就行。当然,你很容易想到A依赖B、B依赖A的问题,也就是循环依赖。当这也是Spring需要考虑的,而且实际的循环依赖会更复杂一些。

讨论到这,你突然能明白XML和@Autowired是干嘛的,其实就是程序员和Spring沟通的一种形式:听好了,A对象是这么创建的,它需要B,而B又依赖C和D。

或者@Autowired也一样:

二者本质上没区别,都是为了表达依赖关系而已。和谁表达?当然是和它的爹:嘤嘤嘤,Spring霸霸,我想要那个Bean激灵~

有人说Spring就是个大Map,也没错,因为底层就是几个Map。但Bean不重要,Bean怎么来的、又为什么要这么来,才是我们需要去思考的。

AOP

AOP最迫切的动力是,要解决那些横跨业务的通用逻辑的复用问题。最典型的就是登录校验、日志等,核心业务几乎都要,但这几个业务又彼此完全独立。AOP本身没有什么了不起的,底层就是代理,要么是JDK动态代理、要么是CGLIB,总之就是返回一个代理对象。

比如,我们可以通过AOP把左右两侧的逻辑编织在一起,使得调用者在调用sayHello()时必然会先打印“方法执行前”,再打印“方法执行后”。如何做到?不需要高深技术,jdk自带的动态代理即可。

你可以把上面的UserServiceProxy看做一个代理工具,你传给他一个原始的userService,他返回你一个代理后的userService,即代理对象。然后,你就可以不用关心日志打印了。

调用sayHello会自动执行上一张图中的invoke逻辑

这和Spring Bean有什么关系?当然有关系。Java Bean已经被Spring认养,是尊贵的Spring Bean了。这点事,当爹的还能不帮你办了?

展开阅读全文

本文系作者在时代Java发表,未经许可,不得转载。

如有侵权,请联系nowjava@qq.com删除。

编辑于

关注时代Java

关注时代Java