El tercer BeanPostProcessor en Spring: InitDestroyAnnotationBeanPostProcessor (01)

En el artículo " Spring BeanPostProcessor II: CommonAnnotationBeanPostProcessor (01) ", se analiza cuando se llama al método postProcessMeredBeanDefinition de la clase CommonAnnotationBeanPostProcessor, el método postProcessMeredBeanDefinition de su clase primaria se llamará a.

1. Descripción general

Veamos primero la clase CommonAnnotationAnnotationBeanPostProcessor. En el artículo anterior, presentamos que esta clase tiene un bloque de código estático que se llamará cuando se inicialice la clase. También hay un constructor predeterminado en esta clase.

público CommonAnnotationBeanPostProcessor () { 
        el setOrder (Ordered.LOWEST_PRECEDENCE - 3. );
         // @PostConstruct anotaciones, que actúa sobre el método 
        setInitAnnotationType (la PostConstruct. clase );
         // @PreDestroy anotaciones, que actúa sobre el método 
        setDestroyAnnotationType (El PreDestroy. clase ); 
        ignoreResourceType ( "javax.xml.ws.WebServiceContext" ); 
    }

El constructor llama a los métodos setInitAnnotationType y setDestroyAnnotationType respectivamente, los dos métodos llaman a los métodos de sus clases principales,

/ ** 
     * Especifique la anotación init para verificar, indicando los 
     métodos de inicialización * para llamar después de la configuración de un bean 
     * <p> Se puede utilizar cualquier anotación personalizada, ya que no se requieren 
     * atributos de anotación. No existe un valor predeterminado, aunque una opción típica 
     * es la anotación JSR-250 { @link javax.annotation.PostConstruct}.
     * / 
    public  void setInitAnnotationType (Clase <? extend Annotation> initAnnotationType) {
         this .initAnnotationType = initAnnotationType; 
    } 

    / **  
     * Especifique la anotación de destrucción para verificar, lo que indica la destrucción
     * métodos para llamar cuando el contexto se está cerrando.
     * <p> Se puede utilizar cualquier anotación personalizada, ya que no se requieren 
     * atributos de anotación. No existe un valor predeterminado, aunque una opción típica 
     * es la anotación JSR-250 { @link javax.annotation.PreDestroy}.
     * / 
    public  void setDestroyAnnotationType (Clase <? extiende Annotation> destroyAnnotationType) {
         this .destroyAnnotationType = destroyAnnotationType; 
    }

 Asigne InitAnnotationType y destroyAnnotationType de InitDestroyAnnotationBeanPostProcessor a las anotaciones @PostConstruct y @PreDestroy, respectivamente.

Segundo, detallado

Como se mencionó anteriormente, cuando se llama al método postProcessMeredBeanDefinition de la clase CommonAnnotationBeanPostProcessor, primero se llamará al método de la clase padre. Veamos el método de CommonAnnotationBeanPostProcessor.

@Override
     public  void postProcessMergedBeanDefinition (RootBeanDefinition beanDefinition, Class <?> BeanType, String beanName) {
         super .postProcessMergedBeanDefinition (beanDefinition, beanType, beanName); 
        InjectionMetadata metadata = findResourceMetadata (beanName, beanType, null ); 
        metadata.checkConfigMembers (beanDefinition); 
    }

Lo anterior es el método postProcessMergedBeanDefinition de CommonAnnotationBeanPostProcessor. Puede ver que se llama al método postProcessMergedBeanDefinition de la clase padre. Los otros métodos se han analizado en el último blog para centrarse en el método postProcessMergedBeanDefinition de InitDestroyAnnotcessBeanPfinan.

@Override
     public  void postProcessMergedBeanDefinition (RootBeanDefinition beanDefinition, Class <?> BeanType, String beanName) { 
        LifecycleMetadata metadata = findLifecycleMetadata (beanType); 
        metadata.checkConfigMembers (beanDefinition); 
    }

Los métodos findLifecycleMetadata y checkConfigMembers se invocan en el método,

privado LifecycleMetadata findLifecycleMetadata (Class <?> clazz) {
         // Determine si lifecycleMetadataCache está vacío 
        si ( this .lifecycleMetadataCache == null ) {
             // Sucede después de la deserialización, durante la destrucción ... 
            devuelva buildLifecycleMetadata (clazz); 
        } 
        // Comprobación rápida primero en el mapa concurrente, con un bloqueo mínimo.
         // Tómelo de lifecycleMetadataCache, y devuelva directamente si existe, genere un objeto LifecycleMetadata y devuelva 
        metadatos LifecycleMetadata = this .lifecycleMetadataCache.get (clazz);
         if (metadata == null) {
             sincronizado ( this .lifecycleMetadataCache) { 
                metadata = this .lifecycleMetadataCache.get (clazz);
                if (metadata == null ) { 
                    metadata = buildLifecycleMetadata (clazz);
                    this .lifecycleMetadataCache.put (clazz, metadata); 
                } 
                devolver metadatos; 
            } 
        } 
        devolver metadatos; 
    }

En el método findLifecycleMetadata, la llamada principal es el método buildLifecycleMetadata. El valor de retorno del método es el objeto LifecycleMetadata, y luego coloca el objeto en lifecycleMetadataCache, entonces lifecycleMetadata debe ser de tipo Map

@Mapa transitoria privada  final  anulable
     <Clase <?>, LifecycleMetadata> lifecycleMetadataCache = new ConcurrentHashMap <> (256);

El método buildLifecycleMetadataf es el siguiente,

privado LifecycleMetadata buildLifecycleMetadata ( clase final <?> clazz) {
         if (! AnnotationUtils.isCandidateClass (clazz, Arrays.asList ( this .initAnnotationType, this .destroyAnnotationType))) {
             devuelve  este .emptyLifecycleMetadata; 
        } 

        Lista <LifecycleElement> initMethods = new ArrayList <> (); 
        Lista <LifecycleElement> destroyMethods = new ArrayList <> (); 
        Clase <?> TargetClass = clazz; 

        hacer {
             finalList <LifecycleElement> currInitMethods = new ArrayList <> ();
             final List <LifecycleElement> currDestroyMethods = new ArrayList <> (); 

            // Determine si hay una anotación initAnnotationType en el método, aquí hay @PostConstruct Annotation 
            ReflectionUMes.sitWithLocals.thodWithLo , method- > {
                 if ( this .initAnnotationType! = null && method.isAnnotationPresent ( this .initAnnotationType)) { 
                    LifecycleElement element = new LifecycleElement (method); 
                    currInitMethods.add (element); 
                    if(logger.isTraceEnabled ()) { 
                        logger.trace ( "Método de inicio encontrado en la clase [" + clazz.getName () + "]:" + method); 
                    } 
                } 
                // Determine si el método tiene la anotación destroyAnnotationType, aquí se refiere a anotación es @PreDestroy 
                SI ( el este .destroyAnnotationType =! nulo && method.isAnnotationPresent ( el este .destroyAnnotationType)) { 
                    currDestroyMethods.add ( nuevo nuevo LifecycleElement (Método));
                     IF (logger.isTraceEnabled ()) { 
                        logger.trace ( "encontrado método de destrucción en la clase ["+ clazz.getName () +"]: "+método); 
                    } 
                } 
            }); 

            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)); 
    }

Del análisis anterior, podemos saber que la función completada por el método postProcessMergedBeanDefinition de InitDestroyAnnotationBeanPostProcessor es almacenar en caché la información del método anotada con @PostConstrunct y @PreDestroy en la clase de lifecycleMetadataCache En otras palabras, está permitido definir métodos modificados por estas dos anotaciones en una clase administrada por resorte, qué métodos tienen esos requisitos, ver el nuevo LifecycleElement arriba, ver la clase LifecycleElement

public LifecycleElement (Método del método) {
             if (method.getParameterCount ()! = 0 ) {
                 lanzar una  nueva IllegalStateException ("La anotación del método del ciclo de vida requiere un método sin argumentos:" + método); 
            } 
            this .method = method;
            this .identifier = (Modifier.isPrivate (method.getModifiers ())? 
                    ClassUtils.getQualifiedMethodName (method): method.getName ()); 
        }

Al observar la excepción anterior, significa que dichos métodos no pueden tener parámetros de método y, si hay parámetros, se generará una excepción.

3. Usa escenarios

Lo anterior analiza el papel del método postProcessMergedBeanDefinition en la clase InitDestroyAnnotationBeanPostProcessor, que consiste en almacenar en caché la información del método de las dos anotaciones @PostConstruct, @PreDestroy en la clase, en cuanto al papel de estas dos anotaciones y cuando los métodos marcados por estas dos anotaciones se llaman Seguirá analizando.

 

La originalidad no es fácil, y las correcciones son bienvenidas.

Supongo que te gusta

Origin www.cnblogs.com/teach/p/12724707.html
Recomendado
Clasificación