前言
  
  使用Spring框架最核心的两个功能就是IOC和AOP。IOC也就是控制反转,我们将类的实例化、依赖关系等都交由Spring来处理,以达到解耦合、利用复用、利于测试、设计出更优良程序的目的。而对用户来说,操作最对的便是注解。在Spring中提供了三类注解方式,下面我们就逐一分析。最后,你会发现,你最常用、看起来最方便的形式确实最不推荐的一种形式。
  
  常见的注入方式
  
  Field注入
  
  @Controller
  
  public class FooController {
  
  @Autowired
  
  // @Resource
  
  private FooService fooService;
  
  此种注解方式,应用最广泛:
  
  注入简单,只需在字段上添加@Autowired或@Resource;
  
  减少大量冗余代码,美观;
  
  新增Field时不需要过多代码修改;
  
  构造函数注入
  
  @Controller
  
  public class FooController {
  
  private final FooService fooService;
  
  private final FooService1 www.michenggw.com fooService1;
  
  @Autowired
  
  public FooController(www.dasheng178.com FooService fooService,FooService1 fooService1) {
  
  this.fooService = fooService;
  
  this.fooService1 = fooService1;
  
  
  @Controller
  
  public class FooController {
  
  private final FooService fooService;
  
  // 当只有一个参数时可不写@Autowired
  
  public FooController(FooService www.ysyl157.com fooService) {
  
  this.fooService = fooService;
  
  Spring4.x推荐的注入方式。对比Field注入:
  
  代码臃肿
  
  新增Field修改麻烦
  
  当Field多余5个时不符合构造方法的基本规范,显得笨重、臃肿;
  
  setter注入
  
  @Controller
  
  public class FooController {
  
  private FooService fooService;
  
  @Autowired
  
  public void setFooService(FooService fooService) {
  
  this.fooService = fooService;
  
  
  Spring3.x推荐的注入方式,但并没有被广泛应用,当初推荐的理由:
  
  解决了构造器注入的笨重;
  
  可以让类在之后重新配置或者重新注入。
  
  为什么Spring4.x推荐构造函数注入
  
  在上面的分析看来,构造函数注入好像并没有显现出来它的优势,但问什么Spring4.x会推翻之前推荐的setter注入,采用构造函数注入呢?官方的理由汇总如下:
  
  依赖不可变:加入了final来约束修饰Field,这条是很显然的;
  
  依赖不可为空:在实例化的时候会检查构造函数参数是否为空,如果为空(未找到改类型的实例对象)则会抛出异常。
  
  单一职责:当使用构造函数注入时,如果参数过多,你会发现当前类的职责过大,需要进行拆分。而使用Field注入时,你并不会意识到此问题。
  
  更利于单元测试:按照其他两种方式注入,当单元测试时需要初始化整个spring的环境,而采用构造方法注入时,只需要初始化需要的类即可,即可以直接实例化需要的类。
  
  避免IOC容器以外环境调用时潜在的NPE(空指针异常)。
  
  避免循环依赖。
  
  保证返回客户端(调用)的代码的时候是完全初始化的状态。
  
  疑问
  
  如果有大量依赖需要注入,怎么办?
  
  如果有大量依赖需要注入说明该类的职责过于复杂,需要遵从单一性原则进行拆分;
  
  其他注入方式是否合理?
  
  存在即合理,根据具体情况可以采用最适合的方式。比如,可以同时使用@Qualifier来达到一些约束限定的目的。也可以使用setter注入和构造函数注入相结合的方式来进行注入。
 

你可能使用了Spring最不推荐的注解方式的更多相关文章

  1. (转)Spring的bean管理(注解方式)

    http://blog.csdn.net/yerenyuan_pku/article/details/69663779 Spring的bean管理(注解方式) 注解:代码中的特殊标记,注解可以使用在类 ...

  2. Spring 的 Bean 管理(注解方式)

    Spring 的 Bean 管理(注解方式) 1. 导入必要的 jar 包和 xml 文件 使用注解需要导入 spring-aop 的 jar 包. applicationContext.xml 文件 ...

  3. Spring的bean管理(注解方式)

    注解:代码中的特殊标记,注解可以使用在类.方法.属性上面,使用注解可实现一些基本的功能.注解的写法是@注解名称(属性=属性值). 使用注解创建对象 第一步,创建Web项目,引入Spring的开发包 第 ...

  4. Spring知识点总结(三)之注解方式实现IOC和DI

        1. 注解概念        所谓注解就是给程序看的提示信息,很多时候都用来作为轻量级配置的方式.        关于注解的知识点,参看java基础课程中java基础加强部分的内容.    2 ...

  5. Spring源码 05 IOC 注解方式

    参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...

  6. Spring MVC 数据验证——validate注解方式

    1.说明 学习注解方式之前,应该先学习一下编码方式的spring注入.这样便于理解验证框架的工作原理.在出错的时候,也能更好的解决这个问题.所以本次博客教程也是基于编码方式.仅仅是在原来的基础加上注解 ...

  7. (四)Spring 的 bean 管理(注解方式)

    目录 前言 使用 aop 的配置文件写法 开启注解扫描 利用注解创建对象 注解方式注入属性 配置文件和注解混合使用 前言 注解可以写在 类.方法.属性 上 : 使用 注解,需要导入 aop 包: 使用 ...

  8. spring AOP (使用AspectJ的注解方式 的aop实现) (6)

    目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...

  9. Spring 实现策略模式--自定义注解方式解耦if...else

    策略模式 定义 定义一簇算法类,将每个算法分别封装起来,让他们可以互相替换,策略模式可以使算法的变化独立于使用它们的客户端 场景 使用策略模式,可以避免冗长的if-else 或 switch分支判断 ...

随机推荐

  1. springboot shiro没有注解解决方案

    颓废的悠然   springboot shiro开启注释 shiroconfiguration中增加 1 2 3 4 5 6 7 @Bean     public AuthorizationAttri ...

  2. SpringBoot学习:添加JSP支持

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)pom中添加依赖: <!-- https://mvnrepository.c ...

  3. Myeclipse - 问题集 - specified vm install not found

    In Eclipse, click the ant file -- Run As -- External Tools Configuration and click on the JRE tab. S ...

  4. PHP程序员如何理解依赖注入容器(dependency injection container)

    背景知识 传统的思路是应用程序用到一个Foo类,就会创建Foo类并调用Foo类的方法,假如这个方法内需要一个Bar类,就会创建Bar类并调用Bar类的方法,而这个方法内需要一个Bim类,就会创建Bim ...

  5. python import vs from import

    https://stackoverflow.com/questions/9439480/from-import-vs-import

  6. Qt-QSplashScreen-程序启动动画

    多数大型应用程序启动时可会在程序完全启动前显示一个启动画面,在程序完全启动后消失,程序启动画面可以显示相关产品的一些信息,使用户在等待程序启动时同时了解产品的相关功能,这也是一种宣传方式. 首先运行界 ...

  7. SQL学习(时间,存储过程,触发器)

    SQL学习 几个操作时间的函数 --datapart 获取时间中的年月日时分秒等部分 select DATEPART(year,current_timestamp); select DATEPART( ...

  8. 165. Merge Two Sorted Lists【LintCode by java】

    Description Merge two sorted (ascending) linked lists and return it as a new sorted list. The new so ...

  9. [Clr via C#读书笔记]Cp18 定制Attribute

    Cp18 定制Attribute 意义 利用Attribute,可以声明性的给自己的代码结构创建注解,从而实现一些特殊的功能:最终在元数据中生成,这种可扩展的元数据信息可以在运行时的时候查询,从而动态 ...

  10. 随机森林random forest及python实现

    引言想通过随机森林来获取数据的主要特征 1.理论根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类,即个体学习器之间存在强依赖关系,必须串行生成的序列化方法,以及个体学习器间不存在强依赖关系 ...