Principio AOP: análisis del código fuente de la anotación @EnableAspectJAutoProxy

1. Descripción de la anotación @EnableAspectJAutoProxy

Agregue la anotación @EnableAspectJAutoProxy a la clase de configuración para habilitar la función AOP de la versión de la anotación. En otras palabras, si desea utilizar la versión de anotación de la función AOP en AOP, debe agregar la anotación @EnableAspectJAutoProxy a la clase de configuración. Primero veamos el código fuente de la anotación @EnableAspectJAutoProxy, de la siguiente manera:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    
    
	 boolean proxyTargetClass() default false;
	 boolean exposeProxy() default false;
}

Como puede verse en el código fuente, @EnableAspectJAutoProxy usa la anotación @Import para introducir el objeto AspectJAutoProxyRegister.class. Entonces, ¿qué es AspectJAutoProxyRegistrar? Continuamos haciendo clic en el código fuente de la clase AspectJAutoProxyRegistrar, de la siguiente manera:

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
    
	 @Override
	 public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    
	
		  AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		
		  AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		  if (enableAspectJAutoProxy != null) {
    
    
			  if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
    
    
			    	AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			   }
			   if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
    
    
			   		AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			   }
		 }
	 }
}

Puede ver que la clase AspectJAutoProxyRegistrar implementa la interfaz ImportBeanDefinitionRegistrar. Mire la definición de la interfaz ImportBeanDefinitionRegistrar, de la siguiente manera:

public interface ImportBeanDefinitionRegistrar {
    
    

	 default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
	   BeanNameGenerator importBeanNameGenerator) {
    
    
	
	  	registerBeanDefinitions(importingClassMetadata, registry);
	 }
	
	 default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    
	 }
}

Función de interfaz ImportBeanDefinitionRegistrar: puede agregar componentes personalizados al contenedor IOC a través de la interfaz ImportBeanDefinitionRegistrar.

En otras palabras, la anotación @EnableAspectJAutoProxy usa el objeto AspectJAutoProxyRegistrar para personalizar el componente y agregar el componente correspondiente al contenedor IOC.

2. Depurar el código fuente de @EnableAspectJAutoProxy

Establezca un punto de interrupción en el método registerBeanDefinitions() de la clase AspectJAutoProxyRegistrar, de la siguiente manera:

inserte la descripción de la imagen aquí

A continuación, usamos el método de depuración para ejecutar el método testAop01() de la clase AopTest. Después de ejecutarse, el programa entra en la posición de punto de interrupción, como se muestra a continuación:

inserte la descripción de la imagen aquí

Se puede ver que el programa se suspendió en el punto de interrupción y la pila de llamadas del método se muestra en la esquina inferior izquierda de IDEA.

En el método registerBeanDefinitions() de la clase AspectJAutoProxyRegistrar, llame primero al método registerAspectJAnnotationAutoProxyCreatorIfNecessary() de la clase AopConfigUtils para registrar el registro. Simplemente mirando el método registerAspectJAnnotationAutoProxyCreatorIfNecessary() no es difícil de entender. El significado literal es: registre un AspectJAnnotationAutoProxyCreator si es necesario.

A continuación, ingresamos el método registerAspectJAnnotationAutoProxyCreatorIfNecessary() de la clase AopConfigUtils, de la siguiente manera:

inserte la descripción de la imagen aquí

En el método registerAspectJAnnotationAutoProxyCreatorIfNecessary() de la clase AopConfigUtils, se llama directamente al método registerAspectJAnnotationAutoProxyCreatorIfNecessary() sobrecargado, y continuamos siguiendo el código, como se muestra a continuación:

inserte la descripción de la imagen aquí

Puede ver que se llama directamente al método registerOrEscalateApcAsRequired() en el método sobrecargado registerAspectJAnnotationAutoProxyCreatorIfNecessary(). En el método registerOrEscalateApcAsRequired(), se pasa el objeto AnnotationAwareAspectJAutoProxyCreator.class.

Pasemos al código de la siguiente manera:

inserte la descripción de la imagen aquí

Podemos ver que en el método registerOrEscalateApcAsRequired(), el tipo de objeto Class recibido es: org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator.

En el método registerOrEscalateApcAsRequired(), primero determine si el registro contiene un bean de tipo org.springframework.aop.config.internalAutoProxyCreator. Como sigue:

inserte la descripción de la imagen aquí

Si el bean de tipo org.springframework.aop.config.internalAutoProxyCreator está incluido en el registro, se realiza el procesamiento correspondiente.Desde el código fuente de Spring, el bean de tipo org.springframework.aop.config.internalAutoProxyCreator se extrae del registro y determine si el valor del nombre del objeto cls es igual al valor beanClassName de apcDefinition. Si no son iguales, obtenga la prioridad de apcDefinition y cls, si la prioridad de apcDefinition es menor que la de cls, establezca beanClassName de apcDefinition en el valor de nombre de cls. En términos relativos, es relativamente simple de entender.

Estamos ejecutando el programa por primera vez aquí, y no ingresaremos la condición If. Continuemos mirando el código, como se muestra a continuación:

inserte la descripción de la imagen aquí

Aquí, use RootBeanDefinition para crear un beanDefinition y pase el objeto Class de org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator como parámetro.

inserte la descripción de la imagen aquí

Sigamos viendo el código, en el método registerOrEscalateApcAsRequired() de la clase AopConfigUtils, se llamará al método registerBeanDefinition() para registrar el componente a través del registro, como se muestra a continuación:

inserte la descripción de la imagen aquí

Y el nombre del bean registrado es org.springframework.aop.config.internalAutoProxyCreator.

A continuación, sigamos mirando el código fuente de registerBeanDefinitions() de la clase AspectJAutoProxyRegistrar, de la siguiente manera:

inserte la descripción de la imagen aquí

Obtenga la información de la anotación @EnableAspectJAutoProxy a través del método atributosFor de la clase AnnotationConfigUtils. A continuación, juzgue si el valor de la propiedad proxyTargetClass es verdadero, y si es verdadero, llame al método forceAutoProxyCreatorToUseClassProxying() de la clase AopConfigUtils; continúe juzgando si el valor de la propiedad de expongaProxy es verdadero, y si es verdadero, llame el método forceAutoProxyCreatorToExposeProxy() de la clase AopConfigUtils.

En resumen, después de agregar la anotación @EnableAspectJAutoProxy a la clase de configuración Spring, AnnotationAwareAspectJAutoProxyCreator se registrará con el contenedor IOC.

A continuación, veamos el diagrama de estructura de la clase AnnotationAwareAspectJAutoProxyCreator

inserte la descripción de la imagen aquí

Resuelva brevemente la relación de herencia principal de la clase AnnotationAwareAspectJAutoProxyCreato, de la siguiente manera:
AnnotationAwareAspectJAutoProxyCreator
-> AspectJAwareAdvisorAutoProxyCreator (clase principal)
-> AbstractAdvisorAutoProxyCreator (clase principal)
-> AbstractAutoProxyCreator (clase principal)
implementa SmartInstantiationAwareBeanPostProcessor, BeanFactory Aware (dos interfaces)

Mirando la relación de herencia, se puede encontrar que esta clase implementa las interfaces Aware y BeanPostProcessor, las cuales están relacionadas con la inicialización de los beans Spring, por lo que se especula que los principales métodos de procesamiento de este tipo provienen de los métodos de implementación de estas dos interfaces. Al mismo tiempo, esta clase también implementa el método order.

El código detallado y el flujo de ejecución de la clase AnnotationAwareAspectJAutoProxyCreator se explicarán en el próximo capítulo.

Supongo que te gusta

Origin blog.csdn.net/qq_36602071/article/details/130001816
Recomendado
Clasificación