spring ioc study notes

spring ioc study notes

The core of ioc is DI, which aims to provide a simpler mechanism to set component dependencies and manage these dependencies throughout the life cycle. Components that require certain dependencies are usually called dependent objects, or target objects in the case of ioc. Usually ioc can be decomposed into two subtypes: dependency injection and dependency lookup. These subtypes are further decomposed into specific implementations of ioc services. Through this definition, we can clearly see that when talking about DI, we are usually talking about ioc, and when talking about ioc, we are not always talking about DI (dependency search is also a form of ioc). When using dependency lookup, the component must have a reference to the dependency. When using dependency injection, the dependency will be injected into the component through the ioc container. There are two types of dependency lookup: dependency pull and context dependency lookup. There are two types of dependency injection: constructor injection and setter injection. Dependency pull is the most common type of ioc. In dependency pull, the dependencies are extracted from the registry as needed.

Spring also provides dependency pull as a mechanism to retrieve components managed by the framework: public class DependencyPull {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/app-context.xml"); MessageRenderer mr = applicationContext.getBean("renderer",MessageRenderer.class); mr.render();}} Context dependency lookup Context dependency Chaochao is similar to dependency pull in some respects. The lookup is performed for the container that manages resources. Rather than from a central registry, and usually executed at a certain set point.

Dependency lookup works by implementing the following interfaces by components. By implementing this interface, a component can send a signal to the container that it wants to obtain dependencies. public interface ManagedComponent {void performLookup(Container container);} public interface Container {Object getDependency(String key);} public class ContextualizedDependencyLookup implements ManagedComponent {private Depency depency; public void performLookup(Container container) {this.depency =(Depency) container .getDependency("myDependency");}

@Override
public String toString() {
    return depency.toString();
}
 

} When the container is ready to pass the dependency to the component, it will call the performLookup() method of each component in turn, and then the component can use the container interface to find the required dependency. Constructor injection When dependencies are provided in the component's constructor, constructor dependency injection occurs. 1. a constructor or a group of constructors is used, and its dependencies are used as parameters. Then the ioc container passes the dependencies to the component when the component is instantiated. An obvious result of using constructor injection is that an object cannot be created without dependencies, so there must be dependencies. public class ConstructorInjection {private Dependency dependency;

public ConstructorInjection(Dependency dependency) {
    this.dependency = dependency;
}

@Override
public String toString() {
    return dependency.toString();
}
 

} Setter injection In setter injection, the ioc container can inject component dependencies through setter methods. The setter method of the component exposes the dependencies that the ioc container can manage. One obvious consequence of using setter injection is that objects can be created without dependencies, and then the dependencies can be provided by calling the setter. In fact, setter injection is the most widely used injection mechanism and one of the simplest ioc mechanisms. public class SetterInjection {private Dependency dependency;

public void SetterInjection(Dependency dependency) {
    this.dependency = dependency;
}

@Override
public String toString() {
    return dependency.toString();
}
 

} The problem of injection and search is now. If there is a choice, which method should be used, injection or search? The answer is definitely injection. On the one hand, the injection has no effect on the component. On the other hand, dependency pull must actively obtain a reference to the registry and interact with it to obtain dependencies. If you use injection, you can freely use classes that are completely separated from the ioc container, and the ioc container manually provides dependent objects for their collaborators; and if you use lookup, your class always depends on the class and interface defined by the container . Another disadvantage of the lookup is that it is difficult to test classes independently of the container, while using injection makes it very easy to test your own components because you can provide dependencies by using appropriate constructors or setters. Setter injection and constructor injection Now the problem comes again. We have chosen to use injection, but should we choose setter injection or constructor injection? The answer is flexible use. Constructor injection is particularly useful when you must have an instance of a dependent class before using the component, but if you use constructor injection, you can declare the requirements for dependencies in a container-independent way. In addition, , Constructor injection also helps to achieve the use of immutable objects. Setter injection is useful in various situations. If a component exposes its dependencies to the container and is happy to provide its own default values, then setter injection is usually the best way to achieve this. Another benefit of setter injection is that it allows to declare dependencies on the interface, although this method is not as useful as the previous method. Setter injection also allows immediate exchange of dependencies for different implementations without the need to create new instances of the parent component. Spring's JMX support makes this feature possible. Perhaps the biggest benefit of setter injection is that it is the least invasive of the injection mechanism. Generally speaking, the injection type should be selected according to the usage. Setter-based injection allows the exchange of dependencies without creating new objects, and it also allows the class to choose appropriate default values without the need to explicitly inject objects. When you want to ensure that dependencies are passed to components and design immutable objects, constructor injection is a good choice.