Using IOC and Di to solve the problem that lazy boss wants to drink coffee but doesn’t want to do it by himself

Time:2021-1-23

In the lazy company, everyone is very lazy, only their programmers are still struggling. The boss wants coffee this day.

public void boss(){
        System.out.println("I want coffee");
    }

At this time, the boss went to the coffee machine.

 public void cofo_jiqi(){
        System.out.println("I'm the coffee machine");
    }

But the boss can’t make coffee now (don’t ask me why not, this is a stupid lazy boss). Then I taught him how to make coffee.

 public void boss(){
        System.out.println("I want coffee");
        //How to make coffee
        Cofo cofo = new Cofo();
        cofo.cofo_jiqi();

    }

Well, the boss successfully made a cup of coffee. But before long, he wanted coffee again. Because this is a lazy company, so the boss is lazy to the extreme. He called his only diligent programmer: Xiao Wang, to make coffee for him.

        chengxuyuan Mr_wang = new chengxuyuan();

Programmer Xiao Wang called

sequenceDiagram->>Xiao Wang:Xiao Wang, what does our company do to you?Xiao Wang->>boss:It's pretty good for me!boss->>Xiao Wang:Well, I have an important thing for you->>boss:What's the matter? Is it a year-end bonus!->>Xiao Wang:Cough, make me a cup of coffee. Everything.

Xiao Wang is fooled around by his boss. He wants to make coffee for him.

chengxuyuan Mr_wang = new chengxuyuan();
 Mr_wang.pao_cofo();

But Xiao Wang’s skill is only to write code, and we have to teach him to make coffee.

class chengxuyuan{
    public void Write(){
        System.out.println("I can write code");
    }
    public void pao_cofo(){
        System.out.println("I can make coffee");
        Cofo cofo = new Cofo();
        cofo.cofo_jiqi();
    }
}

OK, now we teach Xiao Wang to make coffee. At this time, the lazy boss’s right-hand coffee making assistant is Xiao Wang.

Having said so much, in fact, through this example, we have understood the concept of inversion of control in IOC. Before the boss wanted to make coffee, he had to make it himself.

Using IOC and Di to solve the problem that lazy boss wants to drink coffee but doesn't want to do it by himself

The boss needs to know how to use this coffee machine, but how can the boss even learn this kind of low-level thing!!! So at this time we need to use a tool man.

Using IOC and Di to solve the problem that lazy boss wants to drink coffee but doesn't want to do it by himself

At this time, the boss just needs to open his mouth and let Xiao Wang do it. He doesn’t need to move, and he doesn’t need to know how to use the coffee machine. Let Xiao Wang help you. All you need to do is lie on the seat and open your mouth. As bosses, we may all like this kind of natural and unrestrained life, and the program is no exception.

1. Control reversal

Just listen to the name, you should be able to hear one or two, the reversal of control, is not originally belong to their own control of things, in turn, let others help you control. In fact, the meaning of control reversal can be understood in this way. That is, the code is passed to me through control, but actually I don’t rely directly on them. It’s not that my code calls something more generic, but that the framework allows me to insert custom behavior. Such a system design uses the so-called inversion of control (IOC).

Of course, some people will think, what’s the difference between this and my usual new object? What’s the advantage. Of course, in the example I mentioned above, these benefits are certainly not enough, so I will talk about his benefits carefully.

Improving modularity through decoupling

In our actual development process, it is a piece of meat, many people divide, a project many people do, such is modularization. If we usually use new to get objects, it will greatly increase the code coupling. Let two classes become indispensable to each other, this is very should not. If later projects start to be layered and moved, there will be many mistakes if new is still used. In this case, programmers can’t find mistakes one by one, which is too troublesome. So at this time, our IOC container will help us automatically find classes to inject this object into you.

Don’t worry about the process of creating objects, just find the IOC container to get the objects

We can use our Xiao Wang as an IOC container. We just need to think about what kind of coffee we drink, not how we make it. Greatly save the amount of code and logic.

How can we create an IOC container to help us manage objects. Let’s use spring as an example.

Configuration bean

That is to put our object information into the bean

<bean id = "chengxuyuan" class="com.sun.been.chengxuyuan">
    </bean>
    <bean id ="cofo" class="com.sun.been.Cofo">

    </bean>

ID is the name of our object, similar to a in a a = new a().

Class is the address of this class.

Now that we have these two objects, let’s think about it. What else do we need to write?? By the way, since we want Xiao Wang to make coffee for us, we must learn how to make coffee. At this time, we will write a method for him to make coffee.

    <bean id = "chengxuyuan" class="com.sun.been.chengxuyuan">
        <property name="cofo" ref="cofo"></property>
    </bean>
    <bean id ="cofo" class="com.sun.been.Cofo">

    </bean>

OK, let’s see how the code can get these configurations.

First, we need to get the object of programmer Xiao Wang from the IOC container.

 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        chengxuyuan Mr_wang = applicationContext.getBean("chengxuyuan",chengxuyuan.class);

This is a fixed usage, which means to get a container object ApplicationContext and let it read bean.xml The configuration in. Next, we use the object of the container to get the programmer Xiao Wang. The reason why we use the chengxuyuan.class , because it should be a bytecode object. Type conversion is required. Of course, you can also write a strong turn in the front, both can be achieved.

At this time, Xiao Wang called to let him make coffee, but Xiao Wang would not. We need to teach him. At this time, we need to use Di to inject this method.

 public void setCofo(Cofo cofo) {
        this.cofo = cofo;
    }

    private Cofo cofo;

At this time, you must have doubts. Can’t the null pointer exception be written like this, because we didn’t give the object cofo. no! no! no! Here our IOC container has moved from bean.xml We find this object and make it equal to bean.xml We have already configured the object of cofo. So that’s the strength of the IOC container, di injection. (here is a fixed usage. If you want IOC to inject it for you, you can only write it like this.) now let’s run itUsing IOC and Di to solve the problem that lazy boss wants to drink coffee but doesn't want to do it by himself

This coffee is ready.

Did you find that you have been using it bean.xml Is it too much trouble to configure object information. If there are 100 objects, it will be difficult for future operation and maintenance. Do we have a good way to simplify XML. The answer is yes. Spring has specially prepared annotations for us bean.xml The operation in the system. We need to use the following annotations:

@Autowired, as the name suggests, is automatic assembly. Its function is to eliminate getters / setters in Java code and properties in bean properties. Of course, getter depends on individual needs. If private properties need to be provided externally, they should be retained.

@Autowired searches the container for matching beans by type matching by default. When there is only one matching bean, spring injects it into the @ Autowired annotated variable.

Usage is written on top of your method.

//    public void setCofo(Cofo cofo) {
//        this.cofo = cofo;
//    }
    @Autowired
    private Cofo cofo;

This annotation will be used in XML

        <property name="cofo" ref="cofo"/>

Instead.

Instead of the set method, the method can be directly matched. However, it should be noted that if there are more than one bean or no bean, an error will be reported, because the object is matched by type. What should we do once this happens?

@The resource annotation is very similar to @ Autowired annotation

This is a more detailed usage. Let’s talk about the assembly sequence of @ resource

(1) , @ resource has nothing behind it. By default, the bean is matched by the name attribute. If it is not found, the bean is matched by the type

(2) , specify name or type, then match beans according to the specified type

(3) . if name and type are specified, the bean will be matched according to the specified name and type. Any mismatch will result in an error

Then, distinguish between @ Autowired and @ resource annotations

(1) , @ Autowired matches beans by bytype by default, and @ resource matches beans by byname by default

(2) , @ Autowired is the annotation of spring, and @ resource is the annotation of J2EE. When you import the annotation, the package names of these two annotations are clear

Spring belongs to a third party, and J2EE is Java’s own thing. Therefore, it is recommended to use @ resource annotation to reduce the coupling between code and spring.

@Service

@Repository

@Component

The usage of the three is the same, but because of layering, there will be three annotations, and the underlying code is the same. Put this class into IOC container instead of XML

 <bean id = "chengxuyuan" class="com.sun.been.chengxuyuan">

    </bean>
    <bean id ="cofo" class="com.sun.been.Cofo">

    </bean>

The operation of. However, all beans created in this way are singleton patterns. If we need to use the multi instance pattern in our actual development, we can configure @ scope. By default, “Singleton” is singleton, and “prototype” means that a new one will come out every time.

But we have tobe carefulTo configure the IOC container through annotations, our bean.xml We need to add a line of labels to scan our annotations.

    <context:component-scan base-package="com.sun"></context:component-scan>

The parameter package is to fill in the package that needs to be scanned and annotated.

So now our whole code has become like this

package com.sun.been;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

/**
public class test {
    /**
    public static void main(String[] args) {
        /**
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        chengxuyuan Mr_wang = applicationContext.getBean("chengxuyuan",chengxuyuan.class);
        System.out.println("I want coffee");

        Mr_wang.pao_cofo();
    }
    }

/**
@Component
class chengxuyuan{

    @Autowired()
    private Cofo cofo;
    public void Write(){
        System.out.println("I can write code");
    }
    public void pao_cofo(){
        System.out.println("I can make coffee");
        cofo.cofo_jiqi();
    }
}

/**
@Component
class Cofo{
    public void cofo_jiqi(){
        System.out.println("I'm the coffee machine");
    }
        }

bean.xml There’s only one left

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
             http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <context:component-scan base-package="com.sun"></context:component-scan>
</beans>

summary

Before using annotation, the automatic scanning function should be turned on, in which the base package is the package (including subpackages) to be scanned.

<context:component-scan base-package=”cn.test”/>

@Configuration takes a class as an IOC container. If @ bean is registered on a method header, it will be used as a bean in the spring container.

@Scope annotation scope

@Lazy (true) indicates delayed initialization

@Component generally refers to components. When components are not easy to classify, we can use this annotation to annotate.

@Repository is used to label data access components, that is, Dao components.

@Service is used to label business layer components

@Controller is used to label control layer components (such as action in struts)

@Scope used to specify the scope of (used on classes)

@Autowired is assembled by type by default. If we want to use assemble by name, we can use it together with @ qualifier annotation. As follows:

@There are multiple instances of Autowired @ qualifier (“persondaobean”) that can be used together

@Resource is assembled by name by default. When no bean matching the name is found, it will be assembled by type.

@Postconstruct specifies the initialization method (used on methods)

@Predestory is used to specify the destruction method (used on methods)

@Dependson: defines the sequence of bean initialization and destruction

@Primary: during automatic assembly, when multiple bean candidates appear, the bean annotated as @ primary will be the preferred one, otherwise an exception will be thrown

@Postconstruct initialization annotation

@Predestroy destroys annotation and loads the singleton at startup by default

@Async asynchronous method call

This work adoptsCC agreementReprint must indicate the author and the link of this article