我对this section的春季文档感到困惑。
例如,要创建应用程序上下文并使用依赖项注入来配置应用程序,Maven依赖项将如下所示:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.5.RELEASE</version> <scope>runtime</scope> </dependency> </dependencies>
注意,如果不需要针对Spring API进行编译,则可以将作用域声明为运行时,这通常是基本依赖项注入用例的情况。
我了解JSR 330(DI注释)。但是你如何与ApplicationContext
课程脱钩?如果你从中解耦,为什么还要依赖弹簧?
例如,如果spring-context
作为运行时依赖项,可以重写quick start吗?或者什么是&#34;基本依赖注入用例&#34;?
答案 0 :(得分:5)
我认为&#34;基本用例&#34;指的是基于XML的应用程序上下文。该文档说如果您不在代码中直接使用Spring库,那么您不必在编译类路径中包含这些库。这是XML配置的情况,因为Spring相关的所有内容都是用XML配置的,因此不会编译。
在您快速启动时,作者正在使用基于注释的应用程序上下文配置,这需要在编译和运行时都包含Spring库。
示例XML配置: http://www.springbyexample.org/examples/intro-to-ioc-creating-a-spring-application.html
应该只有几个关键点,应用程序代码需要直接访问IoC容器[...]。如果您正在开发Web应用程序,则可能根本不需要直接访问IoC容器,因为它将自动处理控制器及其所需的任何bean的实例化。
我并不完全熟悉它,但您也可以使用JSR330建议使用XML配置来使用注释自动装配bean。 见here。这将允许使用注释,但不需要在编译时配置中包含Spring。
答案 1 :(得分:3)
<强> 1 强>
首先,让我们谈谈DI。
来自Spring Doc的注释,
依赖管理和依赖注入是不同的事情。
Service
对象,而不是使用service = new Service();
创建它,则让spring框架处理该bean的生命周期。依赖关系管理示例:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
</dependencies>
这样你就可以在项目中拥有所有这些jar文件。
spring-context-4.2.5.RELEASE.jar
spring-aop-4.2.5.RELEASE.jar
spring-beans-4.2.5.RELEASE.jar
spring-core-4.2.5.RELEASE.jar
依赖注入示例:
在quick-start示例中,您使用构造函数注入将MessageService
注入MessagePrinter
。你没有在任何地方创建MessageService
。 Spring容器为您创建它。
@Component
public class MessagePrinter {
final private MessageService service;
@Autowired
public MessagePrinter(MessageService service) {
this.service = service;
}
public void printMessage() {
System.out.println(this.service.getMessage());
}
}
@Configuration
@ComponentScan
public class Application {
@Bean
MessageService mockMessageService() {
return new MessageService() {
public String getMessage() {
return "Hello World!";
}
};
}
...
}
<强> 2 强>
现在让我们谈谈transitive dependency and run-time dependency。
传递依赖
这意味着要发现您自己的依赖项所需的库并自动包含它们。
例如,如果您在pom.xml
中指定了依赖关系A和B. A取决于C,D。B取决于E.您不需要在配置中包含C,D,E。
由于传递依赖性,C,D,E将自动包含在内。
运行时依赖
这是一种限制传递依赖的依赖范围。
&#34;此范围表示不需要依赖关系 编译,但是用于执行。它在运行时和测试中 classpaths,但不是编译类路径。&#34;
第3 强>
现在的问题是:对于DI&#34;有什么情况你不需要针对Spring API&#34;进行编译,而是可以将范围设置为运行时?类似问题here。
是的,我能想到的一个例子是Web应用程序。假设我使用带有Spring插件的Strtuts。 (以下示例来自&#34; Struts 2 in Action&#34;来自Manning)
我想告诉Spring创建一个Login
类的实例,以用作请求的操作对象。
向web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
定义一个名为Login
的bean springManagedLoginAction
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="portfolioService" class="manning.chapterNine.utils.PortfolioServiceJPAImpl"/>
<bean id="springManagedLoginAction" class="manning.chapterNine.Login" scope="prototype">
<property name="portfolioService" ref="portfolioService"/>
</bean>
</beans>
在struts-config-login.xml
<action name="Login" class="springManagedLoginAction">
<result type="redirectAction">
<param name="actionName">AdminPortfolio</param>
<param name="namespace">/chapterEight/secure</param>
</result>
<result name="input">/chapterEight/Login.jsp</result>
</action>
答案 2 :(得分:0)
我不确定我是否正确理解了您的问题,但在我看来,为什么您要问为什么在使用JSR-330注释时需要具有Spring-context依赖性。
嗯,从我的观点来看,如果你只使用JSR-330注释,你实际上并不需要对Spring的依赖,但是为了让它们工作,你需要一些理解它们并正确构建的库你和spring-context的依赖图就是这样一个库。
它之所以是运行时依赖性,是因为您可以在运行时切换此提供程序,至少在理论上是这样。
答案 3 :(得分:-1)
您可以在单独的bundle中依赖javax.inject(@Named,@ Inject)来实现bean。它们可用于基于弹簧的项目或任何其他具有自己的DI实现的容器。
以下是javax.inject的基于reworking spring的组件示例(不将项目拆分为不同的bundle) http://www.mkyong.com/spring3/spring-3-and-jsr-330-inject-and-named-example/
答案 4 :(得分:-1)
如果我理解正确,您基本上会询问如何初始化依赖注入器以及如何在类中注入依赖项。在快速入门示例中,您提供的应用程序上下文是在主类中手动创建的。
ApplicationContext context =
new AnnotationConfigApplicationContext(Application.class);
独立应用程序上下文,接受带注释的类作为输入 - 特别是@Configuration-annotated类,但也很简单 使用javax.inject的@Component类型和JSR-330兼容类 注释。允许使用逐个注册类 注册(Class ...)以及使用的类路径扫描 扫描(字符串...)
初始化spring的另一种方法是在你的web.xml中,你可以使用ContextLoaderListner在程序启动时为你引导spring应用程序上下文。
关于如何在web.xml中启动spring的问题已经回答here。