Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations

In the example of the process the bean, also used a series of related notes.

As @PostConstruct @PreDestroy for marking and initialization and destruction methods.

Usually more of a focus on the application, very few people get to know what happens behind it.

Under today to look at their source code, so that they will no longer be for you a black box, but to learn the source code for each technical people is the only way.

People's awareness of things and their practices, often divided into three stages:

1, a first look at things very complicated, just not got a clue, then many people will give up. 2, after a period of time, found a whole did not imagine so difficult, then a lot of people think they have to get up, and then a standstill. 3, along with the deepening of understanding, many details of the discovery process, a lot of aspects to consider is that they can not think of at this time will have a little something into your wisdom, will always belong to you. Unfortunately, this step can reach people who have been rare.

Therefore, to reach the third step of the very few people, if you happen to arrive, then it needs to be done only insisted.

After insist enough time, your effort to pay the cumulative effect of your time (like the integral high number of) will be very obvious, then you already stands at a relatively high position. Under you can experience "would be extremely Ling, list of small hills."

Source learn is to do the first 2:00 and 3:00. It is necessary to know the macro treatment process, but also part of the process to know the details.

And the macro process is easy to understand, very often guess can guess, the challenge is in the details of the deal.

Because the macro corresponding to say, the details corresponding to do, who will talk about the mouth, once done it is not the case.

The reason why the details of the deal is difficult, because a good representation method is not found.

A very important but were not taken seriously views :

To solve a problem, you must first find the problem and describe it (express) out.

Note : Many times we only see the phenomenon, the problem is hidden behind the phenomenon.

I want to express, in fact, how things accurate and a good description of it, is very important.

In the programming world, describe things largely corresponds to the generalized data structure .

First, the description of annotations

Two Class <? Extends Annotation> field to store two notes, set to come through the setter method, instead of writing dead. FIG 0102 follows:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations



Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations



The benefit of this is that if you look down the two annotated Java that is completely possible to create two, replace them, the effect is exactly the same.

Second, the method described

We can think of in a class which uses reflection to find all marked with annotated method, the object is a Method type.

Spring is to do so, but more details of its consideration. FIG 0304 follows:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations



Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations



Method saved up the number of parameters is not surprising, but also requires a method must be 0, i.e., no parameters.

There is also a String type identifier field, the meaning of the word is an identifier.

See below assigned to it, if the method is private, it is the full name (including the class name) method, otherwise it is simply the name of the method (not including the name of the class).

See here, you will find it very strange to secrecy, and then later to explain why.

Also override hashCode and equals methods also rely identifier field to achieve. Description This field is very important.

It will also illustrate possible object of this class as a key Map add use, or to Set collection are actually comparing two objects for equality.

Third, the correspondence relationship between classes and methods described

In fact, we need to know is the appropriate method in each class, so class and associates. Figure 05 is as follows:


Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


We can see that there are two sets of field represents the initialization and destruction methods, a group of type Collection, a group of type Set.

Set types are not repeated, can be disordered as HashSet, it can also be ordered as LinkedHashSet.

Collection type is relatively broad interface, you can also duplicate elements.

Look under construction method, using a Type Collection, duplicate or redundant description passed in initialization or destruction methods, some processing is required, then to Set type, the redundant filtered off.

Fourth, through reflection to find the method marked with annotations

Figure 06 is as follows:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


The whole idea is not difficult, mainly to see a few details here.

这里提到了LocalMethods(即本地方法),指的是一个类自己声明的方法,还有它实现的接口里的默认方法。

就是从这些方法里找出标有初始化和销毁注解的方法。

然后再从这个类的父类里面按照相同的方式找出父类中的这些方法。接着再找父类的父类。

说明这里是支持继承的,如C继承B,B继承A,那么C、B、A中的注解方法都会被找出来。

这就是带来一个问题,即顺序该如何处理,是父类的在前还是子类的在前?

如果对面向对象比较熟悉的话,就会知道初始化属于类的构造,销毁属于类的析构。

可以再进一步,把构造看作是构造方法,把析构看作是析构方法。所以其实就是构造方法和析构方法的调用顺序了。

对于构造方法是父类的先执行,因为子类依赖父类,父类不构建好,子类无法构建。

对于析构方法是子类的先执行,同样是因为子类依赖父类,如果父类先销毁,子类的依赖就不存在了,它怎么可能存活。

可以看出调用顺序正好相反。可以把父类比作房子的一楼,子类比作房子的二楼,子类依赖父类,相当于二楼依赖一楼。

盖楼时先一楼再二楼,对应于构造方法的调用顺序。拆楼时先二楼再一楼,对应于析构方法的调用顺序。

因此,标有初始化注解的方法是父类的方法在前面,子类的方法在后面。标有销毁注解的方法正好倒过来,子类的在前,父类的在后。

构造方法和析构方法是不能被继承和重写的,但是标有注解的方法是可以被继承(只要不是private)或重写(只要不是private/final)的。

这就表明它们之间肯定会有些不同,上面提到的identifier字段,和依赖它实现hashCode和equals方法,就是为了解决这个问题的。

看下它的值,非常特殊:

对于私有方法,identifier字段的值就是方法全名,因为私有方法不能被继续和重写,子类里和父类里定义的同名私有方法,也是不同的两个方法。

所以它们不能互相覆盖,必须全部保留,因此用方法的全名,全名肯定是不同的,所以hashCode也不同。

对于非私有方法(一般是公共和受保护的),identifier字段的值就是方法的简单名,因为非私有方法可以被继续和重写。

子类里和父类里定义的同名非私有方法,虽然也是不同的两个方法,但是它们以反射的方式在子类对象上调用时产生的结果是一样的,都等同于调用子类上的方法。

所以此时只需保留一个就可以了,使用方法的简单名,因为是一样的,所以通过Set时就可以过滤掉一个,实际保留的是父类的,过滤掉的是子类的。

现在我们就明白了Spring设置identifier字段的真正用意了。

:父类中的Method对象,可以在子类的实例上invoke,得到的结果就是子类重写方法后的结果。

五、对找出来的注解方法进行检查

如下图07:


Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


看到把这些方法逐个添加到Set里面,按照定义好的规则进行过滤。

最终的结果就是,私有同名方法都会被保留,非私有同名方法只会保留一个,由于顺序的原因,初始化方法保留的是父类中的,销毁方法保留的是子类中的。

六、通过反射来调用它们

当然,在框架开发中,使用反射来调用是很正常的事情。

如下图0809:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations



Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


到目前为止,我们已经了解了Spring对初始化和销毁方法的处理逻辑。包括方法的表示,如何找出这些方法,方法的过滤去重与排序问题,以及方法的反射调用。

还有最后一个问题,就是这些处理要和bean后处理器的方法结合起来。

七、使用bean后处理器决定调用时机

共涉及到3个方法,

第一个,postProcessMergedBeanDefinition,如下图10:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


该方法虽然与合并后的bean定义相关,但却不是用来处理bean定义的。

它一般用来做一些自我检测的操作或准备和缓存一些相关的元数据的操作。

在这里就是把所有的初始化和销毁方法都找出来,整理好并缓存起来备用。其实这些就相当于元数据的处理。

第二个,postProcessBeforeInitialization,如下图11:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


在这里完成对所有初始化方法的按顺序调用。

Third, postProcessBeforeDestruction, FIG. 12 as follows:

Product Spring Source: processing methods @PostConstruct and @PreDestroy annotations


Here it is completed in order to call for all methods of destruction.

Note :

This article describes the method and are @PostConstruct @PreDestroy two annotation labels.

In addition there are other ways you can specify initialization and destruction methods, the article has been stated.

You also found two notes can be marked on the multiple methods can also be marked in the parent class, and is not subject to access control at impact, because the method can also be private labeled.

And when the parent and child classes in both, but also know the order in which they are calling.

These are the details, even to see the official documents are not written so detailed. This is the source of the benefits of learning. Details of the shows insight.


Guess you like

Origin blog.51cto.com/14455981/2438356