Talk about those extension mechanisms in Spring

High-energy warning ahead: There will be a lot of code in this article.

1. Background

When looking at some framework source code, you can see that many of them will be combined with Spring. For example, the configuration of dubbo:
Talk about those extension mechanisms in Spring
many people actually configure it after configuration, without too much thinking: why can the spring be configured so that it can be recognized, and dubbo can start?

If you also need to make a framework to integrate with Spring, or you want to know how other Spring frameworks integrate with Spring, then you should learn about Spring's extension mechanism.

2. How to expand

This article wants to introduce how to expand from two Spring processes, one is the container initialization process, and the other is the Bean creation process.

2.1 Initialization of the container

To use Spring, the first step must be to initialize the container. There is a refresh method in AbstractApplicationContext that defines how the container is refreshed:
Talk about those extension mechanisms in Spring

The specific process in refresh is as follows: the
Talk about those extension mechanisms in Spring
more common extensions are loading BeanDefinition and executing BeanPostProcessor. The following describes how to expand these two.

2.1.1 Load BeanDefinition

Before introducing loading BeanDefinition, let us first understand what BeanDefinition is. As the name implies, BeanDefinition describes Bean information, such as its class information, attribute information, whether it is a singleton, whether it is lazy loading, etc.

How to load it? There are generally two methods, one is through our xml, and the other is through some extension methods.

The xml is loaded as follows:
Talk about those extension mechanisms in Spring

We configure such a bean definition in spring XML, and he will parse and convert it into our BeanDefinition.

There is another way to extend the XML schema. For a detailed introduction to xsd, please refer to this article: XML schema extension mechanism in Spring. Some students will ask, isn’t there a way to comment? When we are studying, we usually write XML and annotation in books. Annotation actually uses the extension mechanism of XML schema. I will talk about it later.

2.1.1.1 XML schema extension

What is the extension of XML schema?

Spring allows you to define the structure of XML yourself and can parse it with your own bean parser. Here are the 4 steps for custom extension of the XML schema extension mechanism in Spring:

  • Write an XML schema file to describe your node elements.
    Talk about those extension mechanisms in Spring
    Define the demo.xsd file in the resources/META-INF/ directory. Here defines a demo node element, which defines a name field.

  • Write a NamespaceHandler implementation class
    Talk about those extension mechanisms in Spring

  • Write one or more implementations of BeanDefinitionParser (key steps).

Talk about those extension mechanisms in Spring

  • Register the above schema and handler. Create a spring.handler file under the resources/META-INF/ directory and input:
http\:
//www.demo.com/schema/demo = xsd.DemoNameSpaceHandler

, This step maps the url of our previous label to our NamespaceHandler. Create another spring.schemas file and enter:

http\:
//www.demo.me/schema/demo/demo.xsd= META-INF/demo.xsd

This step maps the url of xsd.

Back to annotations, when you configure annotations, you generally use the following figure to configure:
Talk about those extension mechanisms in Spring
but you can see that it is still processed using XML schema extensions. There is a ContextNamespaceHandler in Spring, which registers many parsers:
Talk about those extension mechanisms in Spring
one of them is compnent-scan, defines how to perform annotation scanning in his parse method to obtain annotations:
Talk about those extension mechanisms in Spring

Also using this extension mechanism are AOP, MVC, Spring-Cache, and some of our open source frameworks such as Dubbo.

2.1.1.2 BeanFactoryPostProcessor extension

This mechanism allows us to modify the BeanDefinition before actually instantiating the Bean.

Here I give a practical example. I think many of you have configured database connection pools. Here is Druid as an example:
Talk about those extension mechanisms in Spring

Then we create a druid.properties input:

url
=
jdbc
:
mysql
:
//localhost:3306/test
username
=
root
password
=
123456

For this kind of configuration, I’m satisfied, but there is a problem in the company. The password is stored in the project in clear code. This is not enough. As long as others have the permission to view your project, the password will be leaked, so the general company There will be a unified password storage service, only enough permissions can be used, then we can put the password in the unified storage service, and the password can be used by calling the service, then how do we get it from the remote service Inject the password into our Bean? Then we must use our BeanFactoryPostpRrocessor, the following code inherits PropertyPlaceholderConfigurer (implementation class of BeanFactoryPostpRrocessor):
Talk about those extension mechanisms in Spring

In XML there are:
Talk about those extension mechanisms in Spring

In this way we can have several benefits:

  • Set up a unified configuration center, then we do not need to modify the files in our project, only need to modify in the configuration center page.
  • Set up a unified password center, then we do not need to expose the plaintext in the project, and how to protect the password, then just throw it to the password center.

    2.2 Bean creation

Generally, we will get a Bean in the API as follows: get it
Talk about those extension mechanisms in Spring
through the GetBean operation. We mentioned earlier that if it is a non-lazy loaded singleton bean, it will be loaded when the container is refreshed. If it is a lazy loaded bean, it will be When we get the Bean, we load it according to the BeanDefinition. First, there are two methods in AbstractBeanFactory, one is doCreate, and the other is create to describe how to create a Bean. Here is how the singleton bean is created: The
Talk about those extension mechanisms in Spring
operation flow of doCreateBean is as follows:
Talk about those extension mechanisms in Spring

Creation bean can see the real action in CreateBean, for the real Bean created the following processes:
Talk about those extension mechanisms in Spring
.

2.2.1 Aware interface

Spring provides a lot of Aware interfaces for extension, through Aware we can set many things we want to set:
Talk about those extension mechanisms in Spring

invokeAwareMethod provides three basic types of Aware. If it is ApplicationContext, then another round of Aware injection is performed in ApplicationContextAwareProcessor.

  • BeanNameAware: If Spring detects that the current object implements this interface, it will set the beanName of the object instance to the currency object instance.
  • BeanClassLoaderAware: Inject the ClassLoader that loads the current Bean.
  • BeanFactoryAware: Inject the current BeanFactory container into it.
    If you use ApplicaitonContext type of container, there will be the following:

  • EnvironmentAware: Inject the Environment in the context into it, which can generally be used when obtaining configuration properties.

  • EmbeddedValueResolverAware: Inject EmbeddedValueResolver in the context, generally used for parameter analysis. ResourceLoaderAware: Set the context into it.

ApplicationEventPublisherAware: The ApplicationEventPublisher interface is implemented in ApplicationContext, so you can inject yourself into it.

  • MessageSourceAware: inject itself.

  • ApplicationContextAware: This is what we see more, and will inject its own container into it.

2.2.2 BeanPostProcessor

Earlier we said BeanFactoryPostProcessor, these two names are very similar, BeanFactoryPostProcessor is used to process the BeanDefinition in our BeanFactory, and the Bean has not been generated yet. The BeanPostProcessor is used to process the Bean we generated.
Talk about those extension mechanisms in Spring
There are two methods in BeanPostProcessor, one is for initializing pre-processing, and the other is initializing for post-processing.

There is a special kind of BeanPostProcessor, InstantiationAwareBeanPostProcessor, which will use the returned object instance before we instantiate the process and will not enter the subsequent process.

Actual combat: What is the use of BeanPostProcessor?

If you have a requirement to manage the runtime of each method in the project, you can easily think of using AOP to do it. If you don’t use AOP then you can use the post-processing method of BeanPostProcessor to dynamically change each corresponding bean proxy.

2.2.3 InitializingBean/init-method

Spring provides an extension to our Bean initialization logic:

  • Implement the InitalizingBean interface:
    Talk about those extension mechanisms in Spring
    in the afterPropertiesSet() method we can write our initialization logic.

  • Through xml method:
    Talk about those extension mechanisms in Spring
    define our initialization method in init-method.

2.2.4 DisposableBean/destory-method

As the saying goes, there is no end to life and death. Then we have a living extension, and naturally Spring provides a dead extension. We can also implement our destruction logic through the following two extensions:

  • DisposableBean: Implement the DisposableBean interface
    Talk about those extension mechanisms in Spring

Just implement the destroy method.

  • Realize XML:
    Talk about those extension mechanisms in Spring
    Define the destruction method in destroy-method.

PS: In our Spring container, if you want to automatically call the shutdown method when the JVM is shut down, then we can ((ClassPathXmlApplicationContext) applicationContext).registerShutdownHook(); register the shutdown hook, so that our Bean can be safely destroyed when the JVM is shut down.

3. Summary

This article introduces a number of basic extension points from the introduction of Spring container startup principles and Bean initialization principles. Of course, this part of the extension point is only a part of Spring. Those who are interested can read the Spring documentation or read the Spring source code. If you can master these extensions, you must combine these extensions with Spring when you build your own wheels in the future.

Finally, make an advertisement. If you think this article has an article for you, you can follow my technical public account. Recently, the author has collected a lot of the latest learning materials videos and interview materials, and you can receive them after paying attention. Your attention and forwarding are The greatest support for me, O(∩_∩)O

Talk about those extension mechanisms in Spring

Guess you like

Origin blog.51cto.com/14980978/2544810