Understanding of IoC, DI and AOP in the SSM framework

  The framework encapsulates the code and calling process that programmers need to write repeatedly in ordinary projects. For example, in traditional jsp projects, our controller receives the front-end request and then the programmer needs to develop the Dao layer, which also involves the database. Most of the code for connection and stored procedures are redundant code, and the SSM framework greatly simplifies the development of programmers in the layers below the controller. Only one service layer and mapper layer are needed. The mapper layer uses To connect to the mapper.xml file, you can directly use mapper.xml to develop sql statements, while the database connection and stored procedures are directly responsible for Mybatis, you only need to be responsible for passing the formal parameters and receiving the returned data. , which completes a complete database interaction!

1.1. What is IoC?

  Ioc— Inversion of Control , that is, "inversion of control", is not a technology, but a design idea. In Java development, Ioc means handing over the object you designed to the container control, rather than the traditional direct control inside your object. How to understand Ioc well? The key to understanding Ioc is to clarify "who controls who, controls what, why is it reversed, and which aspects are reversed", then let's analyze it in depth:

 

Who controls who, controls what: In traditional Java SE programming, we create objects directly inside the object through new, and the program actively creates dependent objects; and IoC has a special container to create these objects, that is, the Ioc container to create these objects. Controls the creation of objects; who controls whom? Of course the IoC container controls the object; what? That is, it mainly controls the acquisition of external resources (not just objects including files, etc.).

 

Why is it reversed, and which aspects are reversed: if there is a reverse, there will be a forward rotation. The traditional application is actively controlled by ourselves in the object to directly obtain the dependent object, that is, the forward rotation; while the reverse rotation is caused by the container to help create and inject dependent objects; why reverse? Because the container helps us find and inject dependent objects, the object only passively accepts dependent objects, so it is reversed; which aspects are reversed? The acquisition of dependent objects is reversed.

 

  To illustrate with a legend, the traditional programming is as shown in the figure below, all of which actively create related objects and then combine them:

 

 

 

  When there is an IoC/DI container, these objects are no longer actively created in the client class, as shown in the following figure:

 

1.2 What can IoC do

  IoC is not a technology, but an idea, an important principle of object-oriented programming, which can guide us how to design loosely coupled and better programs. In traditional applications, we actively create dependent objects inside the class, which leads to high coupling between classes and is difficult to test. With the IoC container, the control of creating and finding dependent objects is handed over to the container. By injecting and combining objects, the objects are loosely coupled, which is also convenient for testing, which is conducive to functional reuse, and more importantly, makes the entire architecture of the program very flexible.

  In fact, the biggest change that IoC brings to programming is not from the code, but from the idea, the change of "master-slave transposition" has taken place. The application is originally the boss, and it takes the initiative to acquire any resources, but in the IoC/DI idea, the application becomes passive, passively waiting for the IoC container to create and inject the resources it needs.

  The principle of IoC is based on the Hollywood rule: "don't call us, we'll call you (don't call us, we'll call you)", that is, the IoC container helps the object find the corresponding dependent object and inject it, instead of the object taking the initiative to find. All components are passive (Passive), and all component initialization and invocation are the responsibility of the container.

 

1.3 IoC和DI

 

  DI-Dependency Injection, that is, "dependency injection": the dependency between components is determined by the container at runtime. To put it figuratively, the container dynamically injects a dependency into the component. The purpose of dependency injection is not to bring more functions to the software system, but to increase the frequency of component reuse and build a flexible and extensible platform for the system. Through the dependency injection mechanism, we only need to specify the resources required by the target through simple configuration without any code, and complete our own business logic, without caring where the specific resources come from and who implements them.

The dependencies of the Spring IoC container have two meanings: Bean dependency container and container-injected Bean dependency resources :

  Bean depends on the container: that is to say, the bean depends on the container. The dependency here means that the container is responsible for creating the bean and managing the life cycle of the bean. It is precisely because the container controls the creation of the bean and injects the dependency, that is, the control right is reversed. , which is also the origin of the name of IoC. The dependency here refers to the dependency between the Bean and the container .

  The container injects the bean's dependent resources: the container is responsible for injecting the bean's dependent resources. The dependent resources can be beans, external files, constant data, etc., which are reflected as objects in Java, and the container is responsible for assembling the dependencies between beans. Here Dependency refers to the dependency between beans , which can be considered as the "association", "aggregation" and "combination" relationship between traditional classes and classes .

 

 

The key to understanding DI is: " who depends on whom, why does it need to depend, who injects who, and what is injected ", then let's analyze it in depth:

 

  Who depends on whom: of course the application depends on the IoC container;

 

  Why do you need dependencies: The application needs the IoC container to provide the external resources that the object needs;

 

  Who injects who: It is obvious that the IoC container injects an object of the application, an object that the application depends on;

 

  What is injected: It is to inject external resources (including objects, resources, and constant data) required by an object.

Why apply dependency injection, and what benefits can applying dependency injection bring us?

  Dynamically replace Bean dependent objects, the program is more flexible: Replace Bean dependent objects without modifying source files: After applying dependency injection, since it can be implemented in a configuration file, Bean dependent objects can be dynamically replaced at any time without modifying java source files;

  Better practice of interface-oriented programming, and the code is clearer: only the interface of the dependent object needs to be specified in the bean, the interface defines the function completed by the dependent object, and the dependency is implemented through the container injection;

  It is better practice to use object composition instead of class inheritance: because the IoC container uses injected dependencies, that is, composed objects, it is better to practice object composition.

    Using object combination, the function of a bean may be composed of several functions that depend on the bean. The bean itself may only provide a little function or no function at all, and all are delegated to the dependent bean. The object combination is dynamic and can be replaced more conveniently. Drop the dependent Bean, thereby changing the Bean function;

    If class inheritance is adopted, Bean does not depend on Bean, but uses inheritance to add new functions, and the function is determined at compile time, which is not dynamic, and the use of class inheritance leads to high coupling between Bean and child Bean, Difficult to reuse.

  Increase Bean reusability: Depending on object composition, Beans are more reusable and easier to reuse;

  Reduce the coupling between beans: Since we completely adopt interface-oriented programming, there is no direct reference to the Bean dependency implementation in the code, all references to the interface, and there is no displayed code for creating dependent objects, and these dependencies are injected by the container, which is easy Replacing dependent implementation classes to reduce the coupling between beans and dependencies;

  Clearer code structure: To apply dependency injection, the code structure must be written in a standardized way, so as to better apply some best practices, so the code structure is clearer.

  From the above, we can see that dependency injection is only a means of assembling objects, and the designed class structure is the foundation. If the designed class structure does not support dependency injection, the Spring IoC container cannot inject anything, so fundamentally speaking "How to design the class structure is the key, dependency injection is just a means of assembling objects".

 

  What is the relationship between IoC and DI  ? In fact, they are descriptions of the same concept from different angles. Because the concept of inversion of control is rather vague (it may only be understood as the level of container control objects, it is difficult for people to think of who will maintain the object relationship), so the 2004 master Martin Fowler And given a new name: "dependency injection". Relative to IoC,"dependency injection"clearly describes "the injected object depends on the IoCcontainer to configure the dependent object".

Note: If you want to have a deeper understanding of IoC and DI, please refer to a classic article "Inversion of Control Containers and the Dependency Injection pattern" by the master Martin Fowler, the original address: http://www.martinfowler.com/ articles/injection.html.

1.4 The concept of IoC container

  The IoC container is a container with dependency injection function. The IoC container is responsible for instantiating, locating, configuring objects in the application and establishing dependencies between these objects. The application does not need to directly new related objects in the code, the application is assembled by the IoC container. BeanFactory is the actual representative of the IoC container in Spring.

  How does the Spring IoC container know which objects it manages? This requires a configuration file. The Spring IoC container instantiates and assembles each object in the application through the metadata by reading the configuration metadata in the configuration file. Generally, configuration metadata is based on xml configuration files, and Spring is completely decoupled from configuration files. You can configure metadata in any other possible way, such as annotations, java file-based, and property file-based configurations.

  What is the name of the object managed by the Spring IoC container?

2.1 The concept of Bean

  The objects that make up your application managed by the IoC container are called beans. Beans are objects that are initialized, assembled and managed by the Spring container. Apart from that, beans are no different from other objects in the application. How does IoC determine how to instantiate beans, manage dependencies between beans, and manage beans? This requires configuration metadata, represented in Spring by BeanDefinition, which specifies how to instantiate beans, how to assemble beans, and so on.

  Let's take a look at how the IoC container actually works. Here we analyze it by xml configuration:

  ①Prepare  the configuration file: Just like the previous Hello World configuration file, declaring the bean definition in the configuration file is to configure the metadata for the bean.

  ②The  metadata is parsed by the IoC container:  The Bean Reader of the IoC container reads and parses the configuration file, and generates a BeanDefinition configuration metadata object according to the definition. The IoC container instantiates, configures and assembles beans according to the BeanDefinition.

  ③Instantiate  the IoC container: the container is instantiated by the client to obtain the required beans.

  The execution process is as follows:

2.2 Instantiate Beans

  How does the Spring IoC container instantiate beans? Traditional applications can instantiate beans through new and reflection. The Spring IoC container needs to use the reflection mechanism to create beans according to the configuration metadata in the bean definition. There are mainly the following ways to create beans according to the bean definition in the Spring IoC container:

  1. Use the constructor to instantiate beans: This is the easiest way. The Spring IoC container can create beans using either the default empty constructor or the parameterized constructor. Specify the type of bean to be created as follows:

    ① Use an empty constructor to define, in this way, the class specified by the class attribute must have an empty constructor

1 <bean name="bean1" class="cn.javass.spring.chapter2.HelloImpl2"/>

    ② Use the parameterized constructor to define. In this way, you can use the <constructor-arg> tag to specify the parameter value of the constructor, where index represents the position, and value represents the constant value. You can also specify a reference. Specify the reference to use ref to refer to another A Bean definition:

1 <bean name="bean2" class="cn.javass.spring.chapter2.HelloImpl2">  
2 <!-- 指定构造器参数 -->  
3      <constructor-arg index="0" value="Hello Spring!"/>  
4 </bean>

  2. Use the static factory method to instantiate the Bean. In this way, in addition to specifying the required class attribute, you also need to specify the factory-method attribute to specify the method of instantiating the Bean, and using the static factory method also allows you to specify method parameters. Spring IoC container The method specified by this property will be called to get the bean, and the configuration looks like this:

    ① Let's take a look at the static factory class code HelloApiStaticFactory:

1  public  class HelloApiStaticFactory {  
 2      // Factory method   
3      public  static HelloApi newInstance(String message) {  
 4          // Return the required Bean instance   
5          return  new HelloImpl2(message);  
 6      }  
 7 }  

    ② After the static factory is written, let's configure the Bean definition in the configuration file (resources/chapter2/instantiatingBean.xml):

1 <!-- 使用静态工厂方法 -->  
2 <bean id="bean3" class="cn.javass.spring.chapter2.HelloApiStaticFactory" factory-method="newInstance">  
3      <constructor-arg index="0" value="Hello Spring!"/>  
4 </bean> 

  3. Use the instance factory method to instantiate the Bean. In this way, the class attribute cannot be specified. At this time, the factory-bean attribute must be used to specify the factory bean. The factory-method attribute specifies the method of instantiating the bean, and the instance factory method allows to specify The method parameters, in the same way as using the constructor, are configured as follows:

    ① The instance factory class code (HelloApiInstanceFactory.java) is as follows:

1 public class HelloApiInstanceFactory {  
2     public HelloApi newInstance(String message) {  
3         return new HelloImpl2(message);  
4     }  
5 }

    ② Configure the Bean definition in the configuration file (resources/chapter2/instantiatingBean.xml):

1 <!—1、定义实例工厂Bean -->  
2 <bean id="beanInstanceFactory" class="cn.javass.spring.chapter2.HelloApiInstanceFactory"/>
3 <!—2、使用实例工厂Bean创建Bean -->
4 <bean id="bean4" factory-bean="beanInstanceFactory"factory-method="newInstance">  
5     <constructor-arg index="0" value="Hello Spring!"></constructor-arg>  
6 </bean> 

  Through the above examples, we have basically mastered how to instantiate beans. Have you noticed? These three methods are only different in configuration. From the perspective of the acquisition method, they are exactly the same, and there is no difference. This is also the charm of Spring IoC. Spring IoC helps us create beans, and we can just use them.

3  AOP

  Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing an alternative way of thinking about program structure.
  In addition to classes (classes), AOP provides aspects. Aspects modularize concerns, such as transaction management across multiple types and objects. A key component of Spring is the AOP framework, and you can freely choose whether to use AOP.
  Provides declarative enterprise services, especially as an alternative to EJB declarative services. The most important service is declarative transaction management, which builds on Spring's abstract transaction management.
  Allowing users to implement custom aspects, using AOP to improve the use of OOP can be seen as an enhancement of Spring AOP.

 

4 Summary

  1. Ioc and DI are actually an idea, not a specific technology. We used this idea when we built the SSM project.

  2. First of all, Spring is a large container that can include the entire project, and Ioc and DI are the core ideas for running the entire project.

  3. The operation and cycle of the project are controlled by Ioc, and the request and response of events are controlled by DI

  4. For example: org.springframework.web.servlet.DispatcherServlet front-end configuration class, after the front-end sends a request, Ioc will control the reception of the request, find the controller through the class in spring, rather than the user to receive the front-end request, This is an application of Ioc 

  For example, there is a shopping mall class, and humans want to buy things. With dependency injection, we do not need to create a new shopping mall class, human, and specific commodity class. We only need to configure it in the configuration, and then call the specific purchase method. , pass in the category of items you want to buy, and you can get the desired results through the same period. To put it bluntly, it means that you can save a few new categories, but in large projects, you can save a lot of energy of programmers and focus on development. specific logic. 
  Details example: http://blog.csdn.net/u014563989/article/details/55188673

  5. The idea of ​​DI (dependency injection) can be reflected in the creation of database connections. When the entire project is connected, it is not a new connection when a connection is required, but a connection is created when the project is configured. When it is used, DI will be used by the program, and the developer does not know when and how the program is used, but the function is finally realized.

 

Part of this article is reproduced from: http://jinnianshilongnian.iteye.com/blog/1413846

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324928683&siteId=291194637