This article topic

After reviewing the IOC Design Philosophy in the previous article, I think you have some understanding of IOC. But at the same time, you must have a lot of questions, like,
  1. What are the specific implementations of IOC in Spring?
  2. In what way are they accomplished?
  3. If BeanFactory and ApplicationContext are containers, which one is the underlying IOC container? And what are the real situations they face?


I think there are a lot of questions that come out of the IOC concept. So, for this article I decided to fill that article with a “pit”. So the topic of this article is


IOC implementation in Spring


Many of you have probably seen the Spring MVC source code for handling requests. Now that you’ve seen it, you’ve probably seen the DispatherServlet class, which is the core class responsible for handling requests, acting as a central dispatcher. And we can see that the DispatherServlet does


A constructor method that injects a WebApplicationContext looks like this:

public DispatcherServlet(WebApplicationContext webApplicationContext) {    
        super(webApplicationContext);    
        this.setDispatchOptionsRequest(true);
}Copy the code

This WebApplicationContext can be understood as the context of the Web environment. Those of you who have studied computer science know that context is the storage of data necessary for runtime. The classic is that if a thread is being executed and is being scheduled, the CPU is going to store some of its context data such as “to what line”, “global variables” and so on.


So you might say, what’s the use of this WebApplicationContext? In fact, WebApplicationContext is also an IOC implementation. If you don’t believe me, take a look at the definition on the website:
IO /spring-fram… We can see the following definition:


The
BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object.
ApplicationContext is a sub-interface of BeanFactory.



It says BeanFactory and ApplicationCont


Ext is a Spring IOC container. However, the BeanFactory interface provides an advanced configuration management mechanism to manage it. ApplicationContext is a subclass of it. So, let’s talk about the BeanFactory before we talk about ApplicationContext.

BeanFactory

BeanFactory translates to Bean factory. According to the documentation, it has the following characteristics
  1. The BeanFactory API provides the underlying foundation for Spring’s IoC functionality.
  2. BeanFactory follows the “open closed principle”, opening for external extension and closing for internal modification. It extends other frameworks with BeanFactoryAware/InitializingBean/DisposableBean.
  3. BeanFactory is a core API, which means it’s very simple and has a lot of attention. The implementation of BeanFactory makes no assumptions about the configuration format or any component annotations to use. You can understand that it doesn’t require you to follow any rules or specifications to use Spring because of its abstractness, Compatible with the realization of the different style such as XmlBeanDefinitionReader and AutowiredAnnotationBeanPostProcessor and so on. So that’s what makes Spring’s container so flexible and extensible. You can say this if the interviewer asks you.


Now let’s look at a base of the BeanFactory DefaultListableBeanFactory inherit figure, can see exactly how it through the way of inheritance to achieve the above characteristics.

API

Having looked at the BeanFactory, let’s take a look at its API



Looking at the API, I add:
  1. Does the BeanFactory interface only provide read functionality but no write functionality? In fact, these write functions will be left to its subclasses to implement;
  2. However, BeanProvider is an implementation of deferred lookup and injection in Spring, which will be explained later
  3. We can see that the BeanFactory provides either a name or requireType to fetch the Bean. Does that mean there are only two ways to find it? This is the topic we will cover next – Bean primitive metadata definition


Bean primitive metadata definition

To get beans from the BeanFactory, we first need to get the Bean’s metadata into the Spring IOC container. How to get? Spring provides two approaches:
  1. Configure through annotations
  2. Through the Java API
  3. Configure through XML


Like annotation configuration, we often see Spring Boot using the @Autowire annotation, for example

public class UserService {
    @Autowireprivate 
    UserDao userDao;
}Copy the code

Like Java Configuration, we can also use @configuration / @bean / @import / @dependson, for example

@Configuration
public class SecurityConfig{
    @Bean public UserDao userDao() {
        returnnew UserDao(); }}Copy the code

Not to mention XML configuration, which is something the Spring/Hibernate/Structs 2 era does, for example


<? 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 https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="..."> <! -- collaborators and configurationfor this bean go here -->
    </bean>
</beans>Copy the code



Above is my summary of how to initialize the Bean metadata. You may ask me which of these metadata initialization methods is better and which is worse. At present, according to my cognition, it is not desirable to compare only from convenience. I can only say that all kinds of ways are not bad. There are different application scenarios, and frameworks like Spring Boot, where convention is more important than configuration, tend to favor annotations, but that doesn’t mean XML is obsolete. Because the XML approach will still be used in certain scenarios, or for compatibility with older projects, Spring Boot has been deliberately retained. Therefore, even if there are multiple options, a combination of them may be the best solution in terms of business architecture.


BeanFactory is the most basic container for Spring IOC. Most of the time we don’t fetch beans directly from BeanFactory. How do we use it to fetch beans? Now comes the excellent subclass ApplicationContext!


ApplicationContext

We’ve already said that ApplicationContext is a subclass of BeanFactory. Now LET me begin to refine the information. ApplicationContext is located in the org. Springframework. The context under the package. It is an extension enhancement of BeanFactory. ApplicationContext extensions are framework oriented functions such as
  1. I18n internationalization
  2. There is a powerful Resource abstraction class called Resource and load the ResourceLoader to read URLS and files
  3. Event monitoring mechanism
  4. Multiple hierarchical contexts can be loaded


As you can see from the options above, the Spring framework considers some of the most commonly used features around enterprise-level applications. If you think about it, a feature class that has a lot of features and an IOC container must be like a controller inside the framework that other components can call. So that’s why we don’t usually get beans directly from the BeanFactory, it’s called “outside cohesion.”
Embody it. So how do we get the Bean from ApplicationContext


Suppose we have a configuration file servicees. XML in the resources/ meta-INF directory

<? 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 https://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <bean id="userDao" class="com.jc.test01.dao.UserDao"> 
    </bean> 

</beans>Copy the code
We then use the Java API form to get it


/ / create and configure beans to create and configure BeansApplicationContext context = new ClassPathXmlApplicationContext ("services.xml"); // Retrieve configured Instance search by name + type UserDao UserDao = context.getBean("userDao", UserDao.class); List<String> userList = userdao.getUserNamelist (); // Use configured instance to call the method List<String> userList = userdao.getUserNamelist ();Copy the code



I want to explain the above code. ClassPathXmlApplicationContext is an extension of the ApplicationContext, as said above, the Spring in most cases is through its abundant subclass style to achieve a variety of applications. For example ClassPathXmlApplicationContext it seems that we can know the meaning of it is from the name “from the classPath to load the XML file to the context of” [shows that this is a service oriented XML style class]. Similarly AnnotationConfigApplicationContext annotation style, style FileSystemXmlApplicationContext and file system and so on. If you are interested in debugging its inheritance diagram through IDEA, you will gain a lot.


Inherit the figure





In the pink circles, we can see the interface implemented by the extended features of ApplicationContext. In general, Spring prefers to implement features through composite inheritance, which gives individual classes greater focus and improves encapsulation and utilization.

conclusion

I will answer these questions at the end of this article.


What are the specific implementations of IOC in Spring?
The specific implementations are BeanFactory and ApplicationContext.


In what way are they accomplished?
In fact, as you can see from their class diagrams, they are all composed and inherited. As mentioned above, this has the benefit of improving the functionality of each class, making it more focused on its skills, and facilitating external extension.


If BeanFactory and ApplicationContext are containers, which one is the underlying IOC container? And what are the real situations they face?
The BeanFactory and ApplicationContext are both implementations of IOC. While BeanFactory is focused on providing the most core and basic IOC functionality, ApplicationContext is an IOC implementation that integrates more development-friendly features for enterprise-level applications. The two focus on different directions, non-redundant implementation, do not affect each other.