It is estimated that many friends have been using Spring for a long time. They use spring very frequently. In fact, they have never settled down to study the source code.

Do you feel that way?

One problem with Spring’s source code, however, is that it is too abstract, making it expensive to learn. Therefore, in this paper, we only implement the core functions of Spring, so that we and others can learn the core principles of Spring.

The article is a little long, read patiently! If it helps, remember the triple link!

The core of the spring

Spring-beans are the core of Spring, and everything spring-boot and spring-Cloud is built on this foundation. When someone asks you about Spring, I hope you can talk about your deeper understanding of Spring IOC, rather than just following what others say on the Internet.

In addition, I have collated and collected more than 20 years of interview knowledge, as well as a variety of Java core knowledge points to share with you for free, the following is only part of the screenshot, if you want information, you can also pay attention to the following public account for their own

 

What is the IOC

Inversion of Control, or IoC, is a design principle used in object-oriented programming to reduce coupling between computer code. One of the most common is called Dependency Injection (DI). With inversion of control, when an object is created, it is passed a reference to the object on which it depends by an external entity that regulates all objects in the system. In other words, dependencies are injected into objects.

Why IOC is needed

IoC is a method of decoupling. We know that Java is an object-oriented language, in Java Everything is Object, our program is made up of several objects. As our projects get bigger and more developers work with us, we will have more and more classes, and the number of references between classes will grow exponentially.



Such a project would be a disaster if we introduced the Ioc framework.

The framework maintains the life cycle of classes and references between classes.

Our system would look like this:



At this point, we realized that the IoC framework was responsible for maintaining the classes and injecting them into the required classes.

That is, the user of the class is only responsible for using it, not maintaining it.

Handing over specialized tasks to specialized frameworks greatly reduces the complexity of development.

Quick start

Maven is introduced into

<dependency> <groupId>com.github. Houbb </groupId> <artifactId>ioc</artifactId> <version>0.1.11</version> </dependency>Copy the code

Test preparation

See the test module for all the test code.

  • Apple.java
public class Apple { public void color() { System.out.println("Apple color: red. "); }}Copy the code
  • apple.json

Similar to the XML configuration, we will use JSON for configuration validation for the time being.

[
{"name":"apple","className":"com.github.houbb.ioc.test.service.Apple"}
]
Copy the code

Perform tests.

  • test
BeanFactory beanFactory = new JsonApplicationContext("apple.json");
Apple apple = (Apple) beanFactory.getBean("apple");
apple.color();
Copy the code
  • The log
Apple color: red.
Copy the code
  •  

Spring basic implementation process

instructions

Spring-beans is all about beans.

The BeanFactory is responsible for managing the life cycle of beans. This section shows the simple implementation process in section 1.

Spring Core Process

Spring IoC consists of the following steps.

  1. Initialize the IoC container.
  2. Read the configuration file.
  3. Convert configuration files to container-aware data structures (called BeanDefinition in Spring)
  4. The corresponding objects are instantiated in turn using data structures
  5. Inject dependencies between objects

The abstract BeanDefinition

BeanDefinition is spring’s abstraction of Java Bean properties. Through this abstraction, configuration files can be anything from XML/JSON/Properties/YAML to annotations sweeping. Brings great flexibility to Spring extensions. Considering the simplicity of the implementation, this framework only implements JSON and annotation-based packet scanning. Later, if you have time, you can consider adding the implementation of XML. In fact, it is more about the workload of XML parsing, and the core process has been fully realized.

Implementation source code excerpt

BeanDefinition related

Contains basic information abstractions for Java beans.

  • BeanDefinition.java

The default implementation for DefaultBeanDefinition. Java, is the implementation of the basic Java POJO

Hou * @since 0.0.1 */ public Interface BeanDefinition {/** * name * @return name * @since 0.0.1 * / String getName (); /** * setName * @param name * @since 0.0.1 */ void setName(final String name); /** * class name * @return class name */ String getClassName(); /** * setClassName * @param className className * @since 0.0.1 */ void setClassName(final String className); }Copy the code
  • 1

BeanFactory core management

  • BeanFactory.java
Hou * @since 0.0.1 */ public interface BeanFactory {/** * get the corresponding instance information by name * @param BeanName bean name * @return Object information * @since 0.0.1 */ Object getBean(final String beanName); /** * Get the implementation of the specified type * @param beanName attribute name * @param tClass type * @param <T> generic * @return result * @since 0.0.1 */ <T> T getBean(final String beanName, final Class<T> tClass); }Copy the code
  • 1
  • DefaultBeanFactory.java

For the most basic implementation of the interface, the source code is as follows:

Hou * @since 0.0.1 */ public class implements BeanFactory {/** * Object info map * @since 0.0.1 */ private map <String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(); /** * Object map * @since 0.0.1 */ private map <String, Object> beanMap = new ConcurrentHashMap<>(); @since 0.0.1 */ protected void registerBeanDefinition(final String beanName) Final BeanDefinition BeanDefinition) {/ / here you can add the listener enclosing beanDefinitionMap. Put (BeanDefinition beanName); } @Override public Object getBean(String beanName) { Object bean = beanMap.get(beanName); If (objectutil.isnotnull (bean)) {// This is a singleton. return bean; } BeanDefinition BeanDefinition = beandefinitionmap. get(beanName); if(ObjectUtil.isNull(beanDefinition)) { throw new IocRuntimeException(beanName + " not exists in bean define."); } Object newBean = createBean(beanDefinition); // Add the corresponding listener beanmap. put(beanName, newBean); return newBean; } /** * Create an Object based on Object definition information * @param beanDefinition Object definition information * @return create Object information * @since 0.0.1 */ private Object createBean(final) BeanDefinition beanDefinition) { String className = beanDefinition.getClassName(); Class clazz = ClassUtils.getClass(className); return ClassUtils.newInstance(clazz); } @Override @SuppressWarnings("unchecked") public <T> T getBean(String beanName, Class<T> tClass) { Object object = getBean(beanName); return (T)object; }}Copy the code
  • 1

ClassUtils is the class-based reflection utility class

JsonApplicationContext

Json configuration file based on the basic implementation of the implementation, the use of the first kind of example code.

  • JsonApplicationContext.java
Hou * @since 0.0.1 */ public class JsonApplicationContext extends DefaultBeanFactory { /** * @since 0.0.1 */ private final String fileName; public JsonApplicationContext(String fileName) { this.fileName = fileName; // initialize this.init(); } /** * New TypeReference<List<BeanDefinition>>(){} * </pre> ** https://blog.csdn.net/feeltouch/article/details/83796764 * @ since 0.0.1 * / private void init () {InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); final String jsonConfig = FileUtil.getFileContent(is); List<DefaultBeanDefinition> beanDefinitions = JsonBs.deserializeArray(jsonConfig, DefaultBeanDefinition.class); if(CollectionUtil.isNotEmpty(beanDefinitions)) { for (BeanDefinition beanDefinition : beanDefinitions) { super.registerBeanDefinition(beanDefinition.getName(), beanDefinition); }}}}Copy the code
  • 1

summary

At this point, a basic Spring IOC is basically implemented.

Learning is endless, we strive to move forward together!

Ps: Partners in need can pay attention to the public account below to obtain their own

 

Interview project documents.

Technical documentation

Real Dachang surface classics