根据弹簧对象的名称识别它们
不管使用XML还是Java配置都没有关系,Spring范围大致类似于Map <String,Object>结构。 这意味着您不能有两个名称相同的对象 。 为什么这是一件坏事? 如果您的大型应用程序包含许多@Configuration类或XML文件,则很容易意外地两次使用相同的名称。
最糟糕的是,它们与多个对象一起使用时,它们会默默地相互覆盖,直到实际上只有一个保留在ApplicationContext中为止。 这些对象也可以是不同的类型,而声明顺序才是真正确定哪个对象获胜的因素。 这里的问题是,如果您想基于Spring创建可重用的模块,则基本上将被迫在名称或其他名称中使用前缀,以确保不会出现名称冲突。
根据对象的类别识别Guice对象
Guice范围基本上类似于Map <Class <?>,Object>结构。 这意味着如果不使用额外的元数据(例如,限定词), 就不能拥有两个相同类型的对象 。 这种设计选择有不同的优缺点,但总的来说,我认为这是比较明智​​的选择。 如果创建可重用的模块,则必须确保不导出任何通用类型的对象(例如,字符串)。 使用基于类型的作用域,您始终可以为常见类型创建一个包装的类,而使用基于名称的作用域,您将始终不得不根据幸运的猜测使用唯一的名称。 Guice还具有PrivateModules,因此您可以对所有注入使用Guice,但仅导出范围中的某些对象。  
范例程式码
这是一个Spring应用程序的幼稚示例,由于无声Bean覆盖而中断了运行时。

Main.java

此类实例化应用程序上下文,注册配置类并尝试从上下文中获取MyBean。

package springbreak;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.register(GoodConfig.class);ctx.register(EvilConfig.class);ctx.refresh();ctx.start();System.out.println(ctx.getBean(MyBean.class).getValue());ctx.stop();}
}

MyBean.java

这只是我们期望从应用程序上下文中获得的一种示例类型的Bean。

package springbreak;public interface MyBean {String getValue();
}

GoodConfig.java

这是一个导出MyBean的配置类

package springbreak;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class GoodConfig {private static class MyBeanImpl implements MyBean {public String getValue() {return "I'm a bean";}}@Beanpublic MyBean myBean() {return new MyBeanImpl();}}

EvilConfig.java

此配置类导出名为myBean的String。 这不是一个非常现实的示例,但显示了基本思想。

package springbreak;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class EvilConfig {@Beanpublic String myBean() {return "I'm a string!";}}
分析例子
您可以猜测运行示例时会发生什么吗? 这是基本思想:
  1. GoodConfig导出名称为“ myBean”的MyBeanImpl。
  2. 即使类型不匹配 ,EvilConfig 也会导出一个名称为“ myBean”的字符串替换GoodConfig中的字符串
  3. Main获得NoSuchBeanDefinitionException“未定义[springbreak.MyBean]类型的唯一bean”
因此,基本上将MyBeanImpl替换为String,并且不会有实现MyBean的bean。 最糟糕的部分是, 如果您颠倒@Configuration类的注册顺序,该代码将起作用,因为然后String将被MyBeanImpl替换。 现在,假设您有20个封装良好的模块,这些模块的名称可能会发生冲突……我已经多次碰壁,试图在这种情况下调试问题。
Spring(从3.0.6版开始)无法更改@Configuration类导出的bean的命名。 如果要创建可安全重用的模块,则必须在导出Bean的方法中使用某种完全限定的名称(例如goodConfigMyBean,evilConfigMyBean)。
我喜欢Spring(尤其是非DI容器部件),但是在新项目中,我将拒绝使用从根本上被破坏的库。 是的,两次使用相同的名称是开发人员错误,但是容易出现此类错误的任何库都可被认为比尝试最小化这些错误的替代方法更糟。

参考: Spring vs Guice: Jawsy Solutions技术博客博客上我们JCG合作伙伴 Joonas Javanainen的重要差异之一 。

翻译自: https://www.javacodegeeks.com/2012/06/spring-vs-guice-one-critical-difference.html

Spring vs Guice:重要的一个关键区别相关推荐

  1. guice spring_Spring vs Guice:重要的一个关键区别

    guice spring 根据弹簧对象的名称识别它们 不管使用XML还是Java配置都没有关系,Spring范围大致类似于Map <String,Object>结构. 这意味着您不能有两个 ...

  2. html4与html5效果,浅谈HTML5与HTML4的10个关键区别

    HTML5是HTML标准的下一个版本.越来越多的程序员开始HTML5来构建网站.如果你同时使用HTML4和HTML5的话,你会发现用HTML5从头构建,比从HTML4迁移到HTML5要方便很多.虽然H ...

  3. Spring中ref local与ref bean区别

    为什么80%的码农都做不了架构师?>>>    Spring中ref local与ref bean区别 今天在做SSH框架Demo实例时,在ApplicationResources. ...

  4. 内存和外存的主要区别_内存与外存的关键区别有哪些?

    易失性VS非易失性.内存,例如随机存取内存(RAM),是具有易失性的.这意味着当系统断电时,数据就会丢失.与之相反,外部存储是非易失性的,因此即使没有电源,它也能保存数据. 性能和容量.在大多数情况下 ...

  5. Spring 和 Spring Boot 最核心的 3 大区别,详解!

    概述 对于Spring和SpringBoot到底有什么区别,我听到了很多答案,刚开始迈入学习SpringBoot的我当时也是一头雾水,随着经验的积累.我慢慢理解了这两个框架到底有什么区别,相信对于用了 ...

  6. spring里面 @Controller和@RestController注解的区别

    问题:spring里面 @Controller和@RestController注解的区别 spring里面 @Controller和@RestController注解的区别 Web MVC和REST ...

  7. spring学习笔记01-BeanFactory和ApplicationContext的区别

    spring学习笔记01-BeanFactory和ApplicationContext的区别 BeanFactory 和 ApplicationContext 的区别           BeanFa ...

  8. Spring单例Bean与单例模式的区别

    Spring单例Bean与单例模式的区别在于它们关联的环境不一样,单例模式是指在一个JVM进程中仅有一个实例,而Spring单例是指一个Spring Bean容器(ApplicationContext ...

  9. 机器学习和深度学习的三点关键区别

    机器学习和深度学习的三点关键区别 最简单.最重要的三点区别 深度学习是机器学习的一种子类,通常我们讲的机器学习是传统机器学习方法,比较也是建立于传统机器学习和深度学习两者的区别. 学习的东西不同 训练 ...

最新文章

  1. Android系统中Parcelable和Serializable的区别
  2. C# WebBrowser document.execCommand()解析
  3. JavaScript基础——Date对象
  4. 加号(+)运算符重载
  5. 马拉车(manacher)算法——最长回文(hdu3068)
  6. Qt5学习笔记之串口助手四:增加16进制/ASCII切换、周期发送
  7. 求解偏微分方程开源有限元软件deal.II学习--Step 9
  8. C#获取C# DLL中的指定接口的所有实现实例 - qq_19759475的博客 - CSDN博客
  9. linux系统商店下载的软件到哪了,linux下使用第三方商店安装应用
  10. mysql网络共享_局域网共享mysql
  11. python tkinter教程-事件绑定_详解python tkinter教程-事件绑定
  12. OrCAD(一)简介、安装与基本使用
  13. Spring框架实战入门(超全面,超实用)
  14. 迁移学习_迁移学习简明手册(王晋东)_阅读笔记5-6
  15. Anima2D动画简单理解
  16. Hibernate 关联关系解除
  17. Web安全工具—Sqlmap常用命令和参数(持续更新)
  18. 计算机领域怎么研究区块链,计算机行业深度研究:跨链技术,区块链大航海时代的基石...
  19. 对话雪球创始人方三文:「打工人」如何选行业、找工作、挑老板?|创新大会 2021...
  20. 2017面向对象程序设计(Java)第十一周学习总结

热门文章

  1. Redis两种客户端:lettuce和Jedis的区别
  2. android wtf_WTF连接池
  3. 用jackson转json_用Jackson编写大JSON文件
  4. java批处理 异常处理_Java批处理教程
  5. uaa 授权_使用UAA OAuth2授权服务器–客户端和资源
  6. java heroku_使用Spring Boot和Heroku在20分钟内完成Java的单点登录
  7. openshift_Openshift源中的高可用性Drools无状态服务
  8. jpa 实体图查询_JPA实体图
  9. java 性能调优_Java性能调优调查结果(第二部分)
  10. 使用Selenium WebDriver测试自动化的22条实用技巧