Spring injection control and dependency inversion of notes

Spring technique is most identify Inversion of Control Inversion of Control (IoC) dependency injection dependency injection (DI) mode. Inversion control is a generic concept, it can be used to express many different ways, depending on injection merely one specific example of the inversion control.

Dependency injection (Dependency Injection)

  • effect:

When writing a complex Java applications, you should let the program independent of other Java classes as much as possible to increase the reusability of these classes. Thus, when the unit test, so that they can be tested independently of the other classes.

Dependency Injection helps to bond together these classes, and allow them to remain independent at the same time.

  • rely:

There are instances in Class A Class B, the called Class A to Class B has a dependency. E.g:

public class Human {
    ...
    Father father;
    ...
    public Human() {
        father = new Father();
    }
}

Human class has Class Father, is said to have a dependency on Human class class Father.

A piece of code on the problems:

(1) Now if the father generation mode to be changed, if necessary with new Father (String name) initialization father, Human have to change the code. (2) If you want to test different effects on Human Father target is very difficult, because the father died in the initialization is written in the constructor Human. (3) If the new Father () process is very slow, single measure we wish good father Mock objects have been initialized with out of this process which will be very sleepy.

  • Dependency Injection:

In the previous example, the initialization of a Hard Init depend directly in the constructor, the drawbacks of this approach is that two separate classes enough, not convenient test. Of course, we Init there is another way, such as:

public class Human {
    ...
    Father father;
    ...
    public Human(Father father) {
        this.father = father;
    }
}

In this way, we will father the object passed as a parameter to the constructor. In this way, before calling the constructor Human, you need to initialize a Father good external object. Such non-initialized as dependent on their own initiative, but rather dependent on the incoming external way is called dependency injection.

The benefits of dependency injection is that:

Decoupling between (1) will depend

(2) as it has been decoupled, it is convenient to do unit testing, especially testing Mock.

  • Dependency Injection in Java

Dependency injection There are many ways, in Java, the most commonly used way is achieved through annotations. Marked by the @Inject annotations before the field is declared to achieve automatic injection dependent objects. E.g:

public class Human {
    ...
    @Inject Father father;
    ...
    public Human() {
    }
}

But in fact, if you just write a @Inject annotation, Father target will not be automatically injected, because it relies on a injection framework such as Spring.

Inversion of Control

To better understand the role of inversion of control, let's look at a real life example. A company as a manufacturer of electrical appliances need to put their goods to distributors around the world. After the study they found that different distribution channels have different rules, so they sent a different sales representatives to perform different rules. Later, more and more sales channels, they found that each additional sales channel will add a number of people and a new process, because each channel are dependent on (coupling) its corresponding rules.

Later, the system is too large, so they decided to develop business standards, developing information distribution system, only meet this standard channels to become the company's distributors. Thus, the distribution process to adapt to the distributor by the previous company, became a distributor in turn rely on their own criteria, reversed control, inversion of dependency.

If we put the company and all distributors of software engineering as a subject, then the company developed information distribution system is called IoC container. In the absence of the introduction of distribution information systems (IoC container), distributors wanted the same gear, a gear increase more minutes will increase reliance on other gear, the end result is to cause the system more complex. And after the introduction of the distribution system, each distributor depends only on the distribution system, you can easily add and remove gear.

In a software system, each object like the gear, is coupled to each of the work. In a system of strongly coupled, if a part is not working properly, the system crashed. However, the coupling between objects are inevitable also very necessary, which is the basis for collaborative work. With the application of large-scale systems, dependencies between objects are also becoming increasingly complex, often multiple dependent relationships that exist between objects will appear.

For coupling between objects too high a problem, inversion of control theory came into being solved. It is designed to achieve decoupling between objects. Inversion of Control is an object-oriented design principles, its basic idea is: by means of a "third party" decoupling between objects have dependencies.

A "third party" (the IoC container) in place of the respective gear strongly coupled. In this way, the situation became gear and "third party" is dependent on the inter-dependent conversion gear before each gear rely on "third party", but is independent between the gear and the gear. Here IoC container acts as a "binder" of all objects in the system is bonded together.

IoC container prior to the introduction, if the object A is dependent on object B, then the object A in the initialization process or operation, the need to create their own initiative or subject object B has been created using B. But whether you are creating or use, control in the hands of A. And after the introduction of IoC container, the situation has completely changed, due to the addition of between IoC container object A and object B lost direct contact, so when the need to use the object A object B, IoC container will automatically create a where the object B to the object a is injected needed. In the latter case, the object A process depends on the object B is obtained by a proactive behavior becomes a passive behavior, control over reversed, so this process is called "inversion of control."

Inversion of Control and the Dependency Injection relationship

Simply put, inversion of control is an idea, Dependency Injection is a design pattern.

IoC frame for injection to achieve control dependency inversion. Of course, there are other control implementations inversion, therefore, it is equivalent to the inversion control can not say dependency injection.

Spring Dependence injection

Let's look at this example:

class MovieLister{
    ...
    private MovieFinder finder;
    public void setFinder(MovieFinder finder) {
        this.finder = finder;
    }
    ...
}
class ColonMovieFinder{
    ...
    private String filename;
    public void setFilename(String filename) {
        this.filename = filename;
    }
    ...
}

Here we define two classes, both of which use dependency injection manner dependent on imported from outside, rather than trying to create dependency. The question is, who created the finder and filename, and the finder passed MovieLister, the filename passed ColonMovieFinder? The answer is: Spring IoC container. Dependent objects defined by parameters, factory method parameters and properties of the object constructor, and then by the injection will depend Spring IoC container object created when the bean.

Spring IoC base package is: org.springframework.beans and org.springframework.context

BeanFactory interface is called the Spring IoC container, it can manage any type of object. ApplicationContext is a subinterface of BeanFactory, which adds more feature-rich. Spring IoC container by reading a configuration file to instantiate bean and fitting dependencies between bean. Once initialized Spring IoC container is completed, we can use it to manage all of the bean. Spring means in the bean variety Spring IoC container objects are managed, responsible for bean Spring IoC container by the configuration dependent metadata definition of each other instances, assembly management, bean itself and bean. Configuration metadata is the Spring configuration file, its role is to tell the Spring IoC container should be how to instantiate, assembly and management bean.

Profiles may be defined by xml, java code and annotations like.

Suppose we have as a bean:

public class HelloWorld {
    public void sayHello(String name) {
        System.out.println("Hello " + name);
    }
}
  • To define the bean xml-based way, you need to be written in the services.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.xsd">
    <bean id="helloWorldBean" class="study.spring.bean.HelloWorld">
    </bean>
</beans>

Wherein the bean id is a unique identifier of the bean, this may be cited the bean id other bean, and the class is used to specify the fully qualified class name of the bean.

  • Java-based code and annotated bean definition:
@Configuration
public class HelloWorldConfig {
    @Bean(name="helloWorldBean")
    public HelloWorld helloWorld() {
        return new HelloWorld();
    }
}

Here, we use @Configuration annotation to define the class configuration, use @Bean annotation to define the name attribute bean, use @Bean to define the bean id

Examples of the Spring IoC container is very simple, we only need to tell the location of the Spring IoC container configuration file.

  • Examples of xml based Spring IoC container configuration:
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml");
  • Examples of Spring IoC container configured based java code and notes:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(HelloWorldConfig.class);

Similarly, we can get the bean from the Spring IoC container:

public static void main(String[] args) {
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
    HelloWorld helloWorld = applicationContext.getBean(HelloWorld.class);
    helloWorld.sayHello("test");
}

Through this simple example above, we understand the configuration process Spring IoC, of ​​course, I personally think that the simple example is not necessary to use bean to return instance, you can simply initialize an instance, to achieve results and use IoC container management is almost the same (if you do not need a singleton).

Spring IoC really needs to be managed like the first paragraph of this will depend on the class. MovieLister and ColonMovieFinder back to the example we cited in the first paragraph, we can also use xml and code annotations are two ways to configure the IoC container. Xml embodiment arranged as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="MovieLister" class="spring.MovieLister">
        <property name="finder">
            <ref local="MovieFinder"/>
        </property>
    </bean>
    <bean id="MovieFinder" class="spring.ColonMovieFinder">
        <property name="filename">
            <value>movies1.txt</value>
        </property>
    </bean>
</beans>

Each bean represents an instance of an object (default Singleton pattern , i.e. the lifetime of the program, all objects are only one example, repeated use), by configuring the bean, the IoC container according to the configuration will be activated when bean generated instance. Here Spring IoC container creates MovieFinder Depending on the configuration, at run time the process MovieFinder assigned to the finder MovieLister property, complete dependency injection.

When tested this code, we first generated Spring IoC container according to the configuration (both: ApplicationContext), then acquires from the container MovieLister instance.

public void testWithSpring() throws Exception {
    ApplicationContext apc = new FileSystemXmlApplicationContext("services.xml");
    MovieLister lister = apc.getBean("MovieLister");
    Movie[] movies = lister.moviesDirectedBy("Yimou Zhang");
    asertEquals("Hong Gaoliang", movies[0].getTitle());
}

Please refer to the specific configuration syntax Spring Documentation of Dependencies section.

Original: Large columns  dependency injection and inversion of control Spring notes


Guess you like

Origin www.cnblogs.com/petewell/p/11607322.html