半夜思考之查漏补缺 , Spring 中 Bean 之间的依赖问题

每次看书都会发现本身的不足 . prototype

      当一个 singten 的 Bean 依赖一个 prototype 的 Bean 时 , 若是不加注意 , 会发生一些奇怪的事情 , prototype 变为了 singten 了 , 这是为何呢 ? 设计

      这是 Spring 容器自己的特性 , 当初始化 Spring 容器时 , 容器会预初始化容器中全部的 singleton 的 Bean , 因为 singleton Bean 依赖于 propertype Bean , 所以 , 容器在初始化 singleton Bean 以前会先建立 propertype Bean , 而后将建立好的 propertype Bean 做为属性注入到 singleton Bean 中 , 一旦容器建立好 singleton Bean , 容器在它销毁以前都不会为它第二次注入 propertype Bean , 这样一来 , propertype Bean 却表现出了 singleton 的行为了 , 与设计的初衷违背 . 代理

解决这个问题有两种方式 : 接口

  • 放弃依赖注入 : singleton 做用域的 Bean 每次都须要 propertype 做用域的 Bean 时, 主动向容器请求新的 Bean 实例 , 便可保证每次注入的 Bean , 都是新的 propertype Bean 的实例 . ( 不推荐 )
  • 利用方法注入 : 使用 <lookup-method> 标签指定一个抽象方法和 propertype Bean . 具体实现就是将 singleton Bean 的类声明为一个抽象类 , 并提供一个抽象方法 , 这个抽象方法就是用来注入 propertype Bean 的 . ( 推荐使用 )

下面举一个栗子 : 作用域

       一个猎人 , 有打猎的功能 , 每次打猎都带上猎狗 , 可是每次带的猎狗都不一样 , 也就是符合上面的一个是 singten , 一个是 prototype , 猎人依赖猎狗 . 容器

 

1依赖注入

注 : 利用方法注入的实质使用了代理 , 分为两种代理 , JDK 代理和 cglib 代理 , 若是目标抽象类实现过接口 , Spring 容器会采用 JDK 代理实现抽象方法 , 若是目标类没有实现过接口 , Spring 会采用 cglib 代理 , 实现该抽象方法 . 请求

相关文章
相关标签/搜索