Spring Dependency Injection and Inversion of Control Container Concepts
External
- www.tutorialspoint.com/spring/index.htm
Internal
Overview
Spring is a dependency injection framework. Its main responsibilities are to provide a configuration model that specifies how components should be defined and what are the dependencies between defined components, detect conforming components in the libraries available on the classpath, instantiate the component graph while transitively honoring the dependency relationships - by instantiating the dependency before the dependent and injecting the appropriate dependency references into dependents - and finally expose the components to the application. Instantiation, dependency injection and component life cycle management take place within the Spring IoC container. Support for different application architectures, including messaging, transactions and persistence is built in top of the core container.
Configuration Model
This section refers to component configuration. Configuration as in external data that is provided to the application in form of properties or environment variables, and which potentially modifies the behavior of the application, is addressed in the "Application Configuration Concepts" section.
Spring runtime expects to receive information about what components it should create and how those components should be wired together either in form of XML files or, since Spring 2.5, as annotation-based metadata embedded within the bytecode of the component classes themselves and referred to as Java-based configuration. This information that tells Spring how to build its components and what other components they depend on is called configuration metadata. Configuration metadata expressed as XML is equivalent with configuration metadata provided in form of Java annotations. Either can be used to the same effect. They can also be combined and used together.
Configuration metadata includes the definitions of what constitutes a component - the Java fully qualified classname of the component class, the component's dependencies on other components, the component lifecycle details and where to find component classes. Depending on the metadata format, this information is provided in different formats. For example, in case of XML-based configuration, the fully qualified class name is provided in the "class" attribute of the <bean> element. However, for Java-based configuration, a component class is annotated as a @Component or a similar annotation, so Spring runtime has already the class information when it detects the annotation in the class' bytecode.
XML-based Configuration Metadata
The XML-based configuration historically precedes Java-based configuration. First Spring releases came only with XML configuration support.
This is an example of a simple Spring XML configuration file:
Java-Based Configuration Metadata
Component Detection
Component Lifecycle
Spring IoC Container
The Spring IoC container is also referred to as the core container.
Dependency Injection
Rather than have individual components create and manage the lifecycle of their dependency components, a dependency-injected application relies on container to first create all components, then to inject them into other components that need them. Injection is typically done through constructor arguments or property setters.
Prefer constructor injection to ensure that objects can be instantiate directly. Constructor injection used instead of field injection makes test easier to write.
Spring Dependency Injection Framework
Configuration Model
Configuration Metadata
XML-based Configuration
Representative example of an XML configuration file.
Examples: XML-bases Spring Security Configuration.
Java-based Configuration
Java-based configuration can achieve the same results as XML-based configuration, and it is an alternative to it.
Annotation injection is performed before XML injection, thus the XML configuration overrides the annotations for properties wired through both approaches.
Examples: Java-bases Spring Security Configuration.
Configuration time. Define what that is.
Configuration Class
It is possible to extend the application bootstrap configuration to add more configuration. However, it is good practice to create a new configuration class for each kind of configuration (web, data, security, etc.), keeping the application bootstrap configuration clean and simple.
Autoconfiguration
Both XML-based configuration and Java-based configuration are often unnecessary, as Spring is capable of automatically configuring its components. Automatic configuration employs Spring techniques such as autowiring and component scanning. Clarify the relationship with Spring Boot autoconfiguration.
Component Scanning
Spring runtime capability to automatically discover components from an application's classpath and create them as beans in the application context. This lets you declare classes with annotations like @Component, @Controller, @Service, @Repository etc. to have Spring automatically discover them and register them as components in the application context. Component scanning is enabled by @ComponentScan.
Autowiring
Spring runtime capability to automatically inject components within other beans that they depend on. @Autowired
If the class has just one constructor, it will be considered automatically autowiring target, even without @Autowired.
To Distribute
Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies.
Application Context
The application context provides:
- Bean factory functionality, inherited from ListableBeanFactory.
- Ability to load file resources, inherited from ResourceLoader.
- Ability to publish events to registered listeners, inherited from ApplicationEventPublisher.
- Ability to resolve messages, inherited from MessageSource.
- Inheritance from a parent context.
The application context is created during the bootstrapping phase of a Spring application.
Is the Spring container and application context one and the same thing? Some texts claim so.
Beans
Any non-trivial application consists of many components, each responsible for its own piece of the overall application functionality. These components coordinate with each other. Spring names these these components beans. The Spring container creates and introduces the beans to each other.
Bean Name
Bean ID
Bean alias
Collaborator beans
Describe bean initialization process. Who does it?
Stereotypes
A stereotype annotation denotes the role of the annotated bean in the overall architecture at a conceptual, rather than implementation, level:
- @Component - designates the annotated class as a generic component. Components are singletons.
- @Controller - designates the annotated class as a controller.
- @Indexed - designates the annotated class as a stereotype for the index.
- @Repository - designates the annotated class as a persistence repository.
- @Service - designates the annotated class as a "service", as defined by Domain-Driven Design service.
@Bean What is the fundamental difference between @Bean and the rest (@Component, etc.)?
Bean Scopes
Singleton
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class MySingletonComponent {
...
}
@Configuration
public class MyConfiguration {
@Bean("mySingletonComponent")
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public MySingletonComponent getMySingletonComponent() {
return new MySingletonComponent();
}
}