Business scenario: In the process of developing business using Java, many times a business is composed of various components, each use of these components will not hesitate to use a new component object, in small projects such practice is not wrong, there is no problem. However, in projects with complex business logic and collaborative development, this leads to complex and difficult to manage relationships between business and components, and the coupling between objects becomes very high, which is called “pulling the strings”. This problem is solved in Spring, and its core is the Ioc idea:

Ioc: It’s an Inversion of Control. The translation is inversion of control, which means that the relationships between objects are no longer controlled by traditional programs. Instead, the Spring container has unified control over the creation, coordination, and destruction of objects that only need to complete the business logic.

Here’s a quote from a blog called Bromon on Ioc:

  1. IoC is at the heart of Spring, throughout. IoC, for the Spring framework, means that Spring is responsible for controlling the life cycle of objects and the relationships between objects. For example, how do we find girlfriends? Common situation is, we go everywhere to see where there is a beautiful figure and good MM, and then inquire about their interests, QQ number, telephone number… Find a way to get to know them, give them what they want, and heh heh… The process is complex and profound, and we have to design and face each step ourselves. In traditional program development, if you want to use another object in an object, you have to get it (new one yourself, or look it up from JNDI) and then destroy the object (Connection, etc.). The object is always coupled with other interfaces or classes.
  2. So what does the IoC do? It was a bit like finding a girlfriend through a matchmaking agency, which introduced a third party between me and my girlfriend: the matchmaking agency. Matchmaking management a lot of data of men and women, I can put forward to dating a list, telling it what I want to find a girlfriend, look like michelle reis, for example, figure like Lin Xilei, technology, like zinedine zidane and matchmaking will according to our request, provide a mm, we only need to fall in love with her and get married. Plain and simple, if the matchmaker gives us someone who doesn’t meet our criteria, we throw an exception. The whole process is no longer controlled by me, but controlled by the matchmaking agency, which is like a vessel.
  3. This is the way Spring advocates development: All the classes register in the Spring container, telling Spring what you are and what you need, and then Spring will voluntarily give you what you need when the system is running properly, while also handing you over to other things that need you. The creation and destruction of all classes is controlled by Spring, which means that it is not the reference object that controls the life cycle of an object, but Spring. For a specific object, it used to control other objects, but now all objects are controlled by Spring, so this is called inversion of control.
  4. One focus of IoC is to dynamically provide one object with the other objects it needs while the system is running. This is achieved through DI (Dependency Injection). For example, object A needs to operate on the database. In the past, we always had to write code in A to get A Connection object. With Spring, we just need to tell Spring that A needs A Connection. When the system is running, Spring will make A Connection at the appropriate time and inject it into A like A needle, thus completing control over the relationships between objects. A relies on Connection to function properly, and this Connection is injected into A by Spring, hence the dependency injection name. So how is DI implemented? One of the most important features since Java 1.3 is Reflection, which allows programs to dynamically generate objects, execute object methods, and change object properties at runtime. Spring uses reflection to implement injection.

Let’s take a look at how Spring works

1 public static void main(String[] args) {   
2        ApplicationContext context = new FileSystemXmlApplicationContext(   
3                "applicationContext.xml");   
4        Animal animal = (Animal) context.getBean("animal");   
5        animal.say();   
6    } 
Copy the code

This code is familiar to you, but let’s examine it, starting with ApplicationContext.xml

1 <bean id="animal" class="phz.springframework.test.Cat">   
2        <property name="name" value="kitty" />   
3    </bean>
Copy the code

He has a class PHZ. Springframework. Test. The Cat

1 public class Cat implements Animal {   
2    private String name;   
3    public void say(a) {   
4        System.out.println("I am " + name + "!");   
5    }   
6    public void setName(String name) {   
7        this.name = name;   
8    }   
9 }
Copy the code

Implements PHZ. Springframework. Test. The Animal interface

1public interface Animal {   
2    public void say(a);   
3}
Copy the code

Obviously the above code says I am Kitty! So how does Spring do it? Let’s write our own Spring to see how Spring works. First, we define a Bean class that holds properties owned by a Bean

1/* Bean Id */  
2    private String id;   
3    /* Bean Class */  
4    private String type;   
5    /* Bean Property */  
6    private Map<String, Object> properties = newHashMap<String, Object>(); A Bean contains id, Type, and Properties.Copy the code

Spring then starts loading our configuration file, storing our configured information in a HashMap where the key is the Bean Id and the HasMap value is the Bean, Only then can we get the animal class through the context.getBean(“animal”) method. We all know that Spirng can inject primitive types, and can inject types like List and Map. Let’s take a look at how Spring saves maps

The Map configuration can look like the following

 1<bean id="test" class="Test">   
 2        <property name="testMap">   
 3            <map>   
 4                <entry key="a">   
 5                    <value>1</value>   
 6                </entry>   
 7                <entry key="b">   
 8                    <value>2</value>   
 9                </entry>   
10            </map>   
11        </property>   
12    </bean>
Copy the code

How does Spring save this configuration? , the code is as follows:

 1(beanProperty.element("map") != null) {   
 2                    Map<String, Object> propertiesMap = new HashMap<String, Object>();   
 3                    Element propertiesListMap = (Element) beanProperty   
 4                            .elements().get(0);   
 5Iterator<? > propertiesIterator = propertiesListMap6                            .elements().iterator();   
 7                    while (propertiesIterator.hasNext()) {   
 8                        Element vet = (Element) propertiesIterator.next();   
 9                        if (vet.getName().equals("entry")) {   
10                            String key = vet.attributeValue("key");   
11Iterator<? > valuesIterator = vet.elements()12                                    .iterator();   
13                            while (valuesIterator.hasNext()) {   
14                                Element value = (Element) valuesIterator.next();   
15                                if (value.getName().equals("value")) {   
16                                    propertiesMap.put(key, value.getText());   
17                                }   
18                                if (value.getName().equals("ref")) {   
19                                    propertiesMap.put(key, new String[] { value   
20                                            .attributeValue("bean")});21                                }   
22                            }   
23                        }   
24                    }   
25                    bean.getProperties().put(name, propertiesMap);   
26                } 
Copy the code

The idea of dependency injection is very simple. It is implemented through reflection. When instantiating a class, it uses reflection to call the set method in the class to inject the class properties previously stored in the HashMap. Let’s see how it works. First instantiate a class like this

 1public static Object newInstance(String className) {   
 2Class<? > cls =null;   
 3        Object obj = null;   
 4        try {   
 5            cls = Class.forName(className);   
 6            obj = cls.newInstance();   
 7        } catch (ClassNotFoundException e) {   
 8            throw new RuntimeException(e);   
 9        } catch (InstantiationException e) {   
10            throw new RuntimeException(e);   
11        } catch (IllegalAccessException e) {   
12            throw new RuntimeException(e);   
13        }   
14        return obj;   
15    }  
Copy the code

And then it injects a dependency for that class, like this

 1public static void setProperty(Object obj, String name, String value) {   
 2        Class<? extends Object> clazz = obj.getClass();   
 3        try {   
 4            String methodName = returnSetMthodName(name);   
 5            Method[] ms = clazz.getMethods();   
 6            for (Method m : ms) {   
 7                if (m.getName().equals(methodName)) {   
 8                    if (m.getParameterTypes().length == 1) {   
 9Class<? > clazzParameterType = m.getParameterTypes()[0];   
10                        setFieldValue(clazzParameterType.getName(), value, m,   
11                                obj);   
12                        break;   
13                    }   
14                }   
15            }   
16        } catch (SecurityException e) {   
17            throw new RuntimeException(e);   
18        } catch (IllegalArgumentException e) {   
19            throw new RuntimeException(e);   
20        } catch (IllegalAccessException e) {   
21            throw new RuntimeException(e);   
22        } catch (InvocationTargetException e) {   
23            throw new RuntimeException(e);   
24        }   
25}  
Copy the code

And finally it gives us an instance of this class, and we can use it. Using Map as an example, I wrote code to create a HashMap and inject the HashMap into the class to be injected, like this:

 1if (value instanceof Map) {   
 2Iterator<? > entryIterator = ((Map<? ,? >) value).entrySet()3                        .iterator();   
 4                Map<String, Object> map = new HashMap<String, Object>();   
 5                while (entryIterator.hasNext()) {   
 6Entry<? ,? > entryMap = (Entry<? ,? >) entryIterator.next();7                    if (entryMap.getValue() instanceof String[]) {   
 8                        map.put((String) entryMap.getKey(),   
 9                                getBean(((String[]) entryMap.getValue())[0]));   
10                    }   
11                }   
12                BeanProcesser.setProperty(obj, property, map);   
13            }  
Copy the code

From here, we can generally understand the principle of Spring to implement Ioc. This paper only explains Ioc in simple words and examples. A deeper understanding requires more practical experience. This article references the following:

Blog.csdn.net/jiangyu1013… Blog.csdn.net/it_man/arti…