依赖注入带来的好处可能会上瘾。 使用注入配置应用程序结构比手动完成所有解析要容易得多。 当我们有一些在容器外部实例化的非托管类时,例如在Vaadin UI组件或JPA实体等其他框架中,它们是很难被退出的。 当我们使用域驱动设计时,后者尤其重要。 在Slawek Sobotka主持的 DDD培训期间,我们正在讨论消除骨料工厂中“不良耦合”的选项。 我相信您会承认,最好有一种通用机制能够通过@Inject注释定义的依赖关系来“激发”对象,而不是将所有必要的依赖关系注入特定的工厂,然后通过构造函数,构建器或简单的方法将它们传递给对象二传手。
Spring框架为我们带来了两种不同的解决方案来实现这一要求。 我现在将对它们两个进行描述。 让我们从简单的一个开始。
当我们使用通用存储库,前面提到的聚合工厂或什至任何其他工厂这样的案例时,它仅在确保我们的代码中只有很少的地方可以实例化容器外部的对象时,此功能特别强大。 在这种情况下,我们可以使用AutowireCapableBeanFactory类。 特别是,我们将对两种方法感兴趣:
- 无效的autowireBean(Object existingBean)
- 对象initializeBean(对象existingBean,字符串beanName)
第一个只是不使用特定的后处理器(例如@PostConstruct等)填充我们的bean。 第二种方法另外还应用了工厂回调,例如setBeanName和setBeanFactory,以及带有@PostConstruct的任何其他后期处理程序。 在我们的代码中,它将如下所示:
public abstract class GenericFactory<T> {@Autowiredprivate AutowireCapableBeanFactory autowireBeanFactory;public T createBean() {// creation logicautowireBeanFactory.autowireBean(createdBean);return createdBean;}
}
简单而强大-我最喜欢的作品。
但是,当我们在代码中有很多地方出生对象时,我们该怎么办? 例如在Spring Web应用程序中构建Vaadin布局的情况。 注入调用autowireBean方法的自定义bean配置器对象不会达到生产力的顶峰。 幸运的是,Spring开发人员为我们带来了@Configurable批注。 与方面相关联的此注释将配置每个带注释的对象,即使我们将使用new运算符在容器外部创建它也是如此。 与其他方面一样,我们可以在
- 浪费时间(LTW)
- 建立时间浪费(BTW)。
第一个更易于配置,但是(由于检测)我们依赖于应用程序服务器,在某些情况下这是不可取的。 要使用它,我们需要通过@EnableLoadTimeWeaving注释@Configuration类(或者,如果您喜欢Flintstones和XML配置,则添加<context:load-time-weaver />标记)。完成配置后,只需通过@Configurable注释类:
@Configurable
public class MyCustomButton extends Button {@Autowiredprivate MyAwesomeService myAwesomeService;// handlers making use of injected service
}
第二个选项的设置稍微复杂一些,但是此后运行时会轻很多。 因为现在我们要加载方面直到编译,所以我们必须将Aspectj编译器集成到我们的构建中。 在Maven中,您需要添加一些依赖项:
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.7.3</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>3.2.4.RELEASE</version>
</dependency>
<dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>3.2.4.RELEASE</version>
</dependency>
<dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId><version>1.0</version><scope>provided</scope>
</dependency>
我希望您很好奇为什么在上面可以看到persistence-api。 当我看到在AspectJ编译期间出现“无法确定缺少类型为javax.persistence.Entity的注释”错误时,这对我来说也很奇怪。 答案可以在SpringFramework JIRA的SPR-6819中找到 。 当您在aspectj-maven-plugin中将spring-aspects配置为aspectLibrary时,会发生这种情况。 该问题三年多未解决,因此请更好地习惯。 我们需要做的最后一件事是将上述插件包含在我们的插件部分中。
<plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.5</version><configuration><source>1.7</source><target>1.7</target><complianceLevel>1.7</complianceLevel><showWeaveInfo>true</showWeaveInfo><aspectLibraries><aspectLibrary><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId></aspectLibrary></aspectLibraries></configuration><executions><execution><goals><goal>compile</goal></goals></execution></executions>
</plugin>
这就是所有人!
翻译自: https://www.javacodegeeks.com/2013/09/injecting-spring-beans-into-non-managed-objects.html