one
First of all, let's talk about DI.
Note from Spring Doc ,
Dependency management and dependency injection are two different things.
- Dependency Management - "compile all the necessary libraries (jar files) and get them on the way to the classes at runtime and, possibly, at compile time."
- Dependency Injection, suppose you need a
Service object in your class, instead of creating it using service = new Service(); , you let the spring structure handle the life cycle of this bean.
Dependency Management Example:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.5.RELEASE</version> </dependency> </dependencies>
So you have all these jar files in your project.
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
An example of dependency injection:
In the quick-start example, you enter a MessageService in MessagePrinter by using the constructor insert. You have not created MessageService anywhere. The spring container creates it for you.
@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
Now let's talk about transitive dependency and runtime dependency .
Transitive dependency
This means that you will find libraries that require your own dependencies, and turn them on automatically.
For example, if you specified the dependencies A and B in pom.xml . And it depends on C, D. B depends on E. You do not need to include C, D, E in your configuration. Due to the transitive dependency, C, D, E will be turned on automatically.
Runtime dependency
This is a type of dependency region for limiting the transitive dependency.
"This area shows that the dependency is not required for compilation, but for execution. It is at runtime and the classpaths test, but not the path to compiling the class."
3
Now the question is: is there any case that for DI "you don’t need to compile using the spring API", can you set the scope as runtime instead? A similar question is here .
Yes, one example I can think of is a web application. Suppose I use Strtuts with a spring plugin. (below is an example from "Struts 2 in Action" by Manning)
I want to tell spring to create an instance of the Login class to use as its action object for the request.
add spring web context listener to web.xml
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
define a bean Login named as springManagedLoginAction in 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>
use this bean in action class in 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>