Tag: dependency injection

如何解决松散耦合/dependency injection与富域模型之间的冲突?

编辑:这不是理论层面的冲突,而是实施层面的冲突。 另一个编辑:问题是没有域模型作为仅数据/ DTO与更丰富,更复杂的对象映射,其中Order具有OrderItems和一些calculateTotal逻辑。 具体问题是,例如,Order需要从中国的某些Web服务中获取OrderItem的最新批发价格(例如)。 因此,您运行了一些Spring Service,允许在中国调用此PriceQuery服务。 Order具有calculateTotal,它遍历每个OrderItem,获取最新价格,并将其添加到总数中。 那么您如何确保每个订单都引用此PriceQuery服务? 如何在反序列化,从DB加载和新实例化时恢复它? 这是我的确切问题。 简单的方法是传递对calculateTotal方法的引用,但是如果您的Object在其整个生命周期内部使用此服务该怎么办? 如果它在10种方法中使用怎么办? 每次传递引用都很麻烦。 另一种方法是将calculateTotal移出Order并进入OrderService,但这会打破OO设计,我们会转向旧的“事务脚本”方式。 原帖: 简短版本:富域对象需要引用许多组件,但这些对象会被持久化或序列化,因此它们对外部组件(在本例中为Spring bean:服务,存储库,任何东西)所持有的任何引用都是暂时的并且会被消除。 当对象被反序列化或从DB加载时,需要重新注入它们,但这非常难看,我看不到一种优雅的方法。 更长的版本:有一段时间了,我在Spring的帮助下练习了松耦合和DI。 这对我保持可管理性和可测试性有很大帮助。 不久前,我读了Domain-Driven Design和一些Martin Fowler。 因此,我一直在尝试将我的域模型从简单的DTO(通常是表行的简单表示,只是数据无逻辑)转换为更丰富的域模型。 随着我的域增长并承担新的职责,我的域对象开始需要我在Spring上下文中使用的一些bean(服务,存储库,组件)。 这已成为一场噩梦,也是转换为丰富域名设计最困难的部分之一。 基本上有些点我手动将应用程序上下文的引用注入到我的域中: 当从Repository或其他负责实体加载对象时,因为组件引用是暂时的,显然不会持久化 从Factory创建对象时,因为新创建的对象缺少组件引用 当对象在Quartz作业或其他地方被反序列化时,因为瞬态组件引用被擦除 首先,它很难看,因为我将对象传递给应用程序上下文引用,并期望它通过名称引用它所需的组件。 这不是注射,而是直接拉动。 其次,它是丑陋的代码,因为在所有提到的地方我需要逻辑来注入appContext 第三,它容易出错,因为我必须记住在所有那些地方注入所有这些物体,这比它听起来更难。 必须有一个更好的方法,我希望你能够对它有所了解。

Spring单例和Java singeleton(设计模式)有什么区别?

我正在学习Spring框架,目前正在阅读一本关于它的书。 在本书中,它说Spring单例与Java单例不同? 这是什么意思,有什么区别? 谢谢

什么是Java EE 7属性文件配置的最佳实践建议?

应用程序配置在哪里属于现代Java EE应用程序? 人们有什么最佳实践建议? 通过应用程序配置,我的意思是设置连接设置到其他盒子上的服务,包括外部服务(例如Twitter和我们的内部Cassandra服务器……用于诸如主机名,凭证,重试尝试之类的东西)以及与业务逻辑相关的东西(事物)一个人可能会被诱惑作为常量存储在类中,例如某些东西过期等等。 假设: 我们使用单个EAR文件部署到Java EE 7服务器(Wildfly 8.1),该文件包含多个战争和一个ejb-jar。 我们将部署到各种环境:unit testing,本地开发安装,基于云的UAT基础架构,压力测试和生产环境。 我们的许多房产会因这些环境而异。 如果这是人们推荐的最佳实践,我们不反对将属性配置耦合到DI框架。 所有这些都是为了新的开发,因此我们不必遵守传统的要求或限制。 我们非常关注当前的现代最佳实践。 配置是属于EAR的内部还是外部? 如果在 EAR 之外 ,哪里以及如何最好地可靠地访问它们? 如果在 EAR 内部 ,我们可以将它存储在类路径中的任何位置,以便在执行期间轻松访问。 但是我们必须在每次配置更改时重新组装(并且可能重新构建)。 由于我们将拥有多个环境,因此我们需要一种方法来区分EAR中的文件。 我在这里看到两个选项: 利用预期的文件名(例如cassandra.properties ),然后构建多个特定于环境的EAR(例如, appxyz-PROD.ear )。 构建一个EAR(例如appxyz.ear )并将所有各种环境配置文件放入其中,将环境变量附加到每个配置文件名(例如cassandra-PROD.properties )。 当然还要添加一个环境变量(到vm或其他),以便代码知道要拾取哪个文件。 人们可以推荐哪些最佳实践来解决这一共同挑战? 谢谢。

如何在Spring应用程序上下文中扩展已定义的列表和映射?

想象一下具有不同阶段的分阶段应用程序上下文。 我们从早期阶段开始,定义必要的基础设施。 xml应用程序上下文按顺序加载。 拆分这些文件的原因是扩展/插件机制。 阶段01-default-configuration.xml 我们准备并使用id exampleMapping声明地图,以便稍后使用数据增强它们。 阶段02-custom-configuration.xml (可选) 我们配置exampleMapping并添加一个条目。 阶段03-make-use-of-configuration.xml (必填) 使用定义的map exampleMapping ,无论是自定义配置还是仍然是空的声明映射。 这里的问题是,在第一阶段之后无法向exampleMapping地图添加条目。 Spring抛出了一个exception,即带有id exampleMapping的映射已经存在。 如果我们省略第一阶段,则地图未声明,第三阶段无法解析exampleMapping ,这也会产生exception。 我该如何解决这个问题? 我阅读了Collection merge (spring docs),但这并没有帮助。 是否可以在使用之前将值添加到地图/列表中? 谢谢!

按类型划分的弹簧布线比按名称布线要慢

在我的项目中,我正在尝试迁移所有用法 Foo foo = (Foo) beanFactory.getBean(“name”); 成 Foo foo = beanFactory.getBean(Foo.class); 好处是显而易见的:类型安全性,较少复杂的代码,较少的无用常量等。通常,这些线路位于静态遗留环境中,其中这种布线是唯一的选择。 这一切都很好,直到有一天用户开始抱怨来自Spring internals的缓慢。 所以我启动了一个分析器来找到一个热点 org.springframework.beans.factory.support.AbstractBeanFactory::doGetBean(String, Class, Object[], boolean) 这是一个昂贵的电话 Class.isAssignableFrom(anotherClass) 。 我已经快速创建了一个小的性能测试,找出字符串名称和类型查找之间的速度差异是一个百日咳350次(我正在使用StaticApplicationContext进行此测试FAIW)! 在调查这一点时,我发现SPR-6870的票数很高,但由于某种原因没有得到解决。 这导致我尝试解决这个问题 , 这个问题确实显着改善了这种情况,但仍然比使用String查找要快25倍! 事实certificate,这种尝试只解决了一半的问题:它缓存bean的名称以保存在O(n)迭代上,但仍然必须调用isAssignableFrom来validation类型。 所描述的问题不仅与我的场景有关,而且也适用于使用@Autowired bean,并且在循环内创建bean的情况下可能会感觉很难。 其中一个解决方案是覆盖其中一个bean工厂方法并缓存同一类型的is-this-bean类型的检查结果,但显然这应该在Spring中完成而不是在我自己的代码中完成。 是否还有其他人遇到类似问题并找到解决方案?

Java Spring多个ApplicationContext

SpringContextContext的定义非常模糊,我几乎完成了整本教程,但仍然无法理解ApplicationContext代表什么。 根据Spring API, ApplicationContext是: 用于为应用程序提供配置的中央接口。 这在应用程序运行时是只读的,但如果实现支持,则可以重新加载。 用于访问Spring bean容器的根接口。 这是bean容器的基本客户端视图。 从上面来看,我的问题是: 1)我一直看到书中提到“容器”,容器是指什么? 一个容器是否意味着一个java进程? 或一个容器引用一个ApplicationContext对象? 2)如果我在一个java应用ApplicationContext中实例化两个ApplicationContext (都在主体中),这两个接口是一个中央容器吗? 还是两个单独的实例? 请参阅下面的代码, context1和context2之间的区别是什么? 如果Beans.xml有Singleton,它由context1和context2调用,它们是两个独立的实例还是同一个实例? ApplicationContext context1 = new ClassPathXmlApplicationContext(“Beans.xml”); ApplicationContext context2 = new ClassPathXmlApplicationContext(“Beans.xml”);

如何使用Guice @Inject到现有的对象层次结构?

我有一个现有的对象层次结构,其中一些对象具有需要注入的字段。 此外,还有一些其他对象是使用Google Guice构建的,需要注入对前面描述的对象层次结构中某些对象的引用。 我如何使用Guice进行此类注射? 问题是现有层次结构中的对象不是使用Guice构造的,因此默认情况下不受注入过程的影响。 当然, injector.injectMembers()方法能够注入现有的对象实例,但它不适用于对象层次结构。 对于那些想知道为什么我不能使用Guice构建提到的对象层次结构的人。 此层次结构表示GUI对象,并由GUI框架( Apache Pivot )从声明性GUI描述构建(实际上此过程可以描述为对象反序列化)。 这样接口构造相当简单,我只想将某些服务引用注入接口对象,反之亦然(对于回调)。 我目前要采取的方法如下所述。 为了注入预先存在的对象层次结构,只需让对注入感兴趣的所有对象实现某些接口,如: public interface Injectable { void injectAll(Injector injector); } 然后,这些对象将实现此接口,如下所示: public void injectAll(Injector injector) { injector.injectMembers(this); for (Injectable child : children) child.injectAll(injector); } 然后我只调用mainWindow.injectAll(injector)来获取层次结构中的根对象,并注入所有感兴趣的对象。 不是很好的解决方案,但一方面完成工作。 另一方面,我需要从此层次结构中注入对象。 我想这可以通过为这些对象实现自定义提供程序来完成。 我的问题有更好的解决方案吗? 也许我的方法也有问题?

Methods.class中的代码重用与策略模式和dependency injection

Status: Fendy和Glen Best的答案同样被我接受和尊重,但由于我可以接受并给予赏金,我选择了Fendy的答案。 Scenario: 如果我有一些代码 必须在许多类中 重复使用很多次 (很少有明显的次要参数更改)和并发线程,那么采用哪种方法? 必须重用的代码可以是任何理智的东西(适当考虑静态和非静态上下文和方法制作技术)。 它可以是一个算法,一个DB方法做连接,操作,关闭。 任何东西。 创建一些类MyMethods.class 并将所有这些方法放入其中 。 表1.A 使方法 static并直接调用(由所有类和并发线程)作为MyMethods.someMethod(); 1.B. 使方法 non-static并且在调用它们时,通过MyMethods mm = MyMethods(); mm.someMethod(); instantiate整个类 MyMethods mm = MyMethods(); mm.someMethod(); MyMethods mm = MyMethods(); mm.someMethod(); 使用https://en.wikipedia.org/wiki/Strategy_pattern中声明的策略模式 (此处附带的代码)。 使用https://en.wikipedia.org/wiki/Dependency_injection#Java中所述的dependency injection Problems: 有些人会说使用这种方法进行 unit testing http://en.wikipedia.org/wiki/Unit_testing 是不可能的 , 在换出后者时会遇到麻烦 。 如果你想测试你的类并使用依赖的模拟版本 表1.A 并发调用或多个类会有任何问题吗? 特别是在JDBC static methods中只是一个例子? 1.B. […]

创建新对象和dependency injection之间的区别

创建新对象和dependency injection有什么区别? 请详细解释。

如何使用相同的模型对象初始化JavaFX控制器?

脚本 我正在创建一个GUI,其中多个视图引用相同的模型对象。 我习惯了什么 在Swing中,如果我希望所有视图都引用相同的模型,我会将模型传递给构造函数。 我目前正在做什么 在JavaFX中,我通过在每个视图/控制器加载后在视图/控制器(菜单栏,拆分窗格,制表符……)中使用setter方法来传递模型。 我发现这非常俗气和麻烦。 另外,我发现它不起作用,因为在某些情况下我需要在一些控制器小部件初始化之前已经存在于控制器中的模型。 Lackluster Alternatives (注意:我正在引用这些stackoverflow问题: Controller.java文件中的Javafx 2.0操作方法Application.getParameters() 传递参数JavaFX FXML 带控制器的多个FXML,共享对象 加载FXML时将参数传递给控制器 ) dependency injection 我看过这个网站, http: //www.zenjava.com/2011/10/23/javafx-2-0-fxml-and-spring/,我看了一下google Guice,但我不知道看不到简单地给每个JavaFX视图/控制器提供相同模型对象的方法。 看起来注入会为每个视图/控制器注入不同的模型。 将模型对象保存为公共静态变量 这是一个选项,但目前我不喜欢让公共静态模型如此开放和可用的想法。 显然,我可以使它成为一个私有静态变量,并有getter和setter,但我也不喜欢这个想法。 将参数从调用者传递到控制器 我希望每个控制器在其构造函数中加载自身,并且我希望每个自定义控制器自动注入其父控制器。 例如,卡片概述选项卡会像下面这样加载: public CardOverviewTab() { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(“card_overview_tab.fxml”)); fxmlLoader.setRoot(content); fxmlLoader.setController(this); try { fxmlLoader.load(); } catch (Exception e) { e.printStackTrace(); } } 并且SingleGameSetup控制器将卡概述选项卡自动注入变量: public class […]