
文章插图
这个方法关键是上面的两步,第一步找出所有注解的方法,第二步执行对应的方法,第二步比较简单,就是调用了反射操作,我们重点关注在第一步findLifecycleMetadata方法 。
/** * 查找指定类型的生命周期元数据. */private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {// lifecycleMetadataCache为空,则重新创建生命周期元数据.if (this.lifecycleMetadataCache == null) {// HAppens after deserialization, during destruction...return buildLifecycleMetadata(clazz);}// 采用双重检查锁机制来进行快速检查,尽量减少对锁的使用 。// 首先进行快速检查,只需最少的锁竞争.// Quick check on the concurrent map first, with minimal locking.LifecycleMetadata metadata = https://www.isolves.com/it/cxkf/kj/2022-06-21/this.lifecycleMetadataCache.get(clazz);if (metadata == null) {// 加锁处理synchronized (this.lifecycleMetadataCache) {metadata = this.lifecycleMetadataCache.get(clazz);if (metadata == null) {// 关键方法,构建LifecycleMetadatametadata = buildLifecycleMetadata(clazz);this.lifecycleMetadataCache.put(clazz, metadata);}return metadata;}}return metadata; }查看关键的方法buildLifecycleMetadata的源码如下:/** * 创建生命周期元数据. */private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {// 判断当前Bean是否包含@PostContruct,@PreDestroy,如果不包含,直接返回if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {return this.emptyLifecycleMetadata;}// 初始化相关元数据List<LifecycleElement> initMethods = new ArrayList<>();// 销毁相关的元数据List<LifecycleElement> destroyMethods = new ArrayList<>();Class<?> targetClass = clazz;do {final List<LifecycleElement> currInitMethods = new ArrayList<>();final List<LifecycleElement> currDestroyMethods = new ArrayList<>();// 遍历类中的methodsReflectionUtils.doWithLocalMethods(targetClass, method -> {// 判断方法是有@PostConstruct注解if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {LifecycleElement element = new LifecycleElement(method);currInitMethods.add(element);if (logger.isTraceEnabled()) {logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);}}// 判断方法是有@PreDestroy注解if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {currDestroyMethods.add(new LifecycleElement(method));if (logger.isTraceEnabled()) {logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);}}});initMethods.addAll(0, currInitMethods);destroyMethods.addAll(currDestroyMethods);// 查找父类targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :new LifecycleMetadata(clazz, initMethods, destroyMethods)); }复制代码该方法主要是遍历bean对应的class以及父class中包含@PostConstruct、@PreDestroy注解的方法,构建出LifecycleMetadata对象 。
有一个问题,上面查找其实用的都是initAnnotationType、@PostConstruct、@PreDestroy属性,那他们是在上面时候设置为@PostConstruct、@PreDestroy呢?
我们可以看父类
CommonAnnotationBeanPostProcessor的构造方法,它在实例化CommonAnnotationBeanPostProcessor这个bean的时候设置 。

文章插图
public CommonAnnotationBeanPostProcessor() {setOrder(Ordered.LOWEST_PRECEDENCE - 3);// 设置PostConstructsetInitAnnotationType(PostConstruct.class);setDestroyAnnotationType(PreDestroy.class);ignoreResourceType("javax.xml.ws.WebServiceContext");// java.naming module present on JDK 9+?if (jndiPresent) {this.jndiFactory = new SimpleJndiBeanFactory();} }何时实例化CommonAnnotationBeanPostProcessor那么CommonAnnotationBeanPostProcessor这个Bean处理器是在什么时候装载到容器中呢?只有它装载到容器中后,才会执行对应的方法 。

文章插图
- 在创建容器的时候,会创建所有的BeanPostProcessors Bean 。
- 在创建CommonAnnotationBeanPostProcessor这个Bean的时候,就会调用对应的构造方法,设置对应的PostConstruct注解 。
那又是什么时候把
推荐阅读
- 欲速则不达的意思,欲速则不达的理解-
- 呆若木鸡理解,呆若木鸡背后的大道理-
- |看了马思纯的早期生活照,我理解了什么是真正的“又纯又欲”
- 如何理解曹操说的生子当如孙仲谋,曹操生子当如孙仲谋上一句-
- 对爱情的理解和感受,对爱情的理解是什么-
- 什么叫做无欲则刚,无欲则刚怎么理解-
- 有好儿子不如有好媳妇怎么理解,有个好儿子不如有个好媳妇什么意思-
- 关于孔子对于仁和礼的理解,孔子认为“仁”和“礼”是互为表征的,仁是礼的本质-
- 怎么理解贫贱夫妻百事哀,贫贱夫妻百事哀中的哀怎么读-_1
- 梦溪笔谈阅读理解及答案,《梦溪笔谈》受到的启示-
