Recently, I bought this Spring Introductory Book: springInAction. I browsed roughly and felt pretty good. Just a little bit of getting started. Manning's books are still good. Although I don't focus on Manning like those who only read Manning books, I read it through it with reverence and passion. Once again, I accepted the core concepts of Spring such as IOC, DI, and AOP. Let me talk about my opinion on IOC and DI first.
IOC (DI): In fact, the concept of the core Spring architecture is not that complicated, and it is not as obscure as described in some books. Java programmers all know that each business logic in a java program requires at least two or more objects to collaborate. Generally, when each object uses its partner object, it must use a syntax like newobject() to complete the application work of the partner object. You will find that the coupling between objects is high. The idea of IOC is: Spring containers to realize the creation and coordination of these interdependent objects. Objects only need to have relationship business logic itself. In this regard, the responsibility for how an object gets his collaborative object is reversed (IOC, DI).
This is my experience of Spring's IOC. DI is actually another way of saying IOC. DI was first proposed by Martin Fowler in a paper in early 2004. He concluded: What is the control reversed? That is: the way of obtaining dependent objects is reversed.
If you don't understand this core concept yet: Here we quote a simple and easy-to-understand answer found on a blog called Bromon:
IOC and DI
First, I want to talk about IOC (InversionofControl, control inversion). This is the core of spring, throughout. For the spring framework, spring is responsible for controlling the life cycle of an object and the relationship between objects. What does this mean? To give a simple example, how do we find a girlfriend? A common situation is that we go everywhere to see where we have beautiful and good-looking women, and then inquire about their interests, QQ numbers, phone numbers, IP numbers, iQ numbers..., find ways to get to know them, give them what they like, and then hehe... This process is complex and profound, and we must design and face each link ourselves. The same is true for traditional program development. In an object, if you want to use another object, you must get it (new one by yourself, or query one from JNDI). After use, the object must be destroyed (such as Connection, etc.), and the object will always be combined with other interfaces or classes.
So how does IoC do it? It’s a bit like finding a girlfriend through a marriage agency, and introducing a third party between me and my girlfriend: a marriage agency. The marriage agency manages a lot of information about men and women. I can provide a list to the marriage agency and tell it what kind of girlfriend I want to find, such as looking like Michelle Reis, having a figure like Lin Xilei, singing like Jay Chou, having a speed like Carlos, and having a technology like Zidane. Then the marriage agency will provide an mm according to our requirements. We just need to fall in love and get married. It's simple and clear. If the candidates given to us do not meet the requirements, we will throw an exception. The whole process is no longer controlled by me, but is controlled by a container-like institution like a marriage agency. This is the development method advocated by Spring. All classes will be registered in the spring container to tell spring what you are and what you need. Then spring will give you what you want when the system is running to the appropriate level, and at the same time handing you over to other things that need you. All classes are created and destroyed by spring, which means that the object that controls the life cycle of an object is no longer the object that references it, but spring. For a specific object, it used to control other objects, but now all objects are controlled by spring, so this is called control inversion.
One of the key points of IoC is to dynamically provide an object with other objects it needs during the system operation. This is achieved through DI (DependencyInjection). For example, object A needs to operate the database. In the past, we always wrote code in A to obtain a Connection object. With spring, we only need to tell spring that a Connection is needed in A. As for how to construct this Connection and when to construct it, A does not need to know. When the system is running, spring will create a Connection at the appropriate time, and then inject it into A like an injection, thus completing the control of the relationship between each object. A needs to rely on Connection to run normally, and this Connection is injected into A by spring, and the name of dependency injection comes from this. So how is DI implemented? An important feature after Java 1.3 is reflection, which allows the program to dynamically generate objects, execute objects methods, and change objects' properties when running. Spring is injected through reflection. For related information about reflection, please refer to javadoc.
After understanding the concepts of IoC and DI, everything will become simple and clear, and the rest of the work is just to pile up blocks in the framework of spring.
Let's learn how Spring works.
public static void main(String[] args) { ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml"); Animal animal = (Animal) context.getBean("animal"); animal.say(); }You must be familiar with this code, but let's analyze it. First, applicationContext.xml
<bean id="animal"> <property name="name" value="kitty" /> </bean>
He has a class phz.springframework.test.Cat
public class Cat implements Animal {private String name;public void says() {System.out.println("I am " + name + "!");}public void setName(String name) {this.name = name;}}Implemented the phz.springframework.test.Animal interface
public interface Animal { public void says(); }Obviously the above code outputs Iamkitty!
So how does Spring do it?
Next, let’s write a Spring ourselves to see how Spring works!
First, we define a Bean class, which is used to store properties owned by a Bean
/* Bean Id */ private String id; /* Bean Class */ private String type; /* Bean Property */ private Map<String, Object> properties = new HashMap<String, Object>();
A bean includes id, type, and Properties.
Next Spring starts loading our configuration file and saves the configuration information in a HashMap. The key of HashMap is the Bean's Id and the value of HasMap is the Bean. Only in this way can we obtain the Animal class through the context.getBean("animal") method. We all know that Spirng can inject basic types, and can inject types like List and Map. Next, let's take Map as an example to see how Spring is saved
The Map configuration can be like the following
<bean id="test"> <property name="testMap"> <map> <entry key="a"> <value>1</value> </entry> <entry key="b"> <value>2</value> </entry> </map> </property> </bean>
How does Spring save the above configuration? The code is as follows:
if (beanProperty.element("map") != null) { Map<String, Object> propertiesMap = new HashMap<String, Object>(); Element propertiesListMap = (Element) beanProperty.elements().get(0); Iterator<?> propertiesIterator = propertiesListMap.elements().iterator(); while (propertiesIterator.hasNext()) { Element vet = (Element) propertiesIterator.next(); if (vet.getName().equals("entry")) { String key = vet.attributeValue("key"); Iterator<?> valuesIterator = vet.elements().iterator(); while (valuesIterator.hasNext()) { Element value = (Element) valuesIterator.next(); if (value.getName().equals("value")) { propertiesMap.put(key, value.getText()); } if (value.getName().equals("ref")) { propertiesMap.put(key, new String[] { value.attributeValue("bean") }); } } } } bean.getProperties().put(name, propertiesMap); }Next, let's go to the core part. Let's see how Spring is dependency injection. In fact, the idea of dependency injection is also very simple. It is implemented through the reflection mechanism. When instantiating a class, it injects the class attributes stored in HashMap into the class by reflecting the set method in the class. Let's see how it is done.
First instantiate a class, like this
public static Object newInstance(String className) {Class<?> cls = null;Object obj = null;try {cls = Class.forName(className);obj = cls.newInstance();}catch (ClassNotFoundException e) {throw new RuntimeException(e);}catch (InstantiationException e) {throw new RuntimeException(e);}catch (IllegalAccessException e) {throw new RuntimeException(e);}return obj;}Then it injects the dependencies of this class into it, like this
public static void setProperty(Object obj, String name, String value) {Class<? extends Object> clazz = obj.getClass();try {String methodName = returnSetMthodName(name);Method[] ms = clazz.getMethods();for (Method m : ms) {if (m.getName().equals(methodName)) {if (m.getParameterTypes().length == 1) {Class<?> clazzParameterType = m.getParameterTypes()[0];setFieldValue(clazzParameterType.getName(), value, m, obj);break;}}}}}catch (SecurityException e) {throw new RuntimeException(e);}catch (IllegalArgumentException e) {throw new RuntimeException(e);}catch (IllegalAccessException e) {throw new RuntimeException(e);}}Finally, it returns an instance of this class to us and we can use it. Let's take Map as an example to see how it is done. The code I wrote is to create a HashMap and inject the HashMap into the class that needs to be injected, like this
if (value instanceof Map) { Iterator<?> entryIterator = ((Map<?, ?>) value).entrySet().iterator(); Map<String, Object> map = new HashMap<String, Object>(); while (entryIterator.hasNext()) { Entry<?, ?> entryMap = (Entry<?, ?>) entryIterator.next(); if (entryMap.getValue() instanceof String[]) { map.put((String) entryMap.getKey(), getBean(((String[]) entryMap.getValue())[0])); } } BeanProcesser.setProperty(obj, property, map); }OK, so we can use Spring to create the class for us. Isn’t it difficult? Of course Spring can do more than this. This example program only provides part of Spring's most core dependency injection function.
This article has referenced a large number of articles and cannot thank you one by one. Thank you here together. I apologize for your copyright infringement. I hope it will be helpful to everyone!
Summarize
The above is all the content of this article about the detailed explanation of Spring IOC principles, and I hope it will be helpful to everyone. Interested friends can continue to refer to this site:
A brief understanding of Spring's IOC, AOP and code examples
Detailed introduction to Spring's Ioc simulation implementation
If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!