5.x primavera Fuente invokeBeanFactoryPostProcessors diez Excursión de tres

procesador de ejecución BeanFactoryPostProcessor

Hablando frente a un método para hacer frente a la interfaz BeanDefinitionRegistryPostProcessor, después de que el tratamiento ha terminado ahora para comenzar el tratamiento interfaz BeanFactoryPostProcessor, y también el primer BeanDefinitionRegistryPostProcessortipo de tratamiento, seguido por una costumbre BeanFactoryPostProcessortipo de procesamiento.

invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//BeanDefinitionRegistryPostProcessor的
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);//自定义的BeanFactoryPostProcessor

Tipo de procesador BeanDefinitionRegistryPostProcessor ejecución

Principalmente ConfigurationClassPostProcessorde postProcessBeanFactory, existe la costumbre, nuestra principal preocupación ConfigurationClassPostProcessores.

	private static void invokeBeanFactoryPostProcessors(
			Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

		for (BeanFactoryPostProcessor postProcessor : postProcessors) {
			postProcessor.postProcessBeanFactory(beanFactory);
		}
	}

ConfigurationClassPostProcessor 的 postProcessBeanFactory

clase de configuración mejorada está haciendo, y luego añadir un ImportAwareBeanPostProcessorpost-procesador.

@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		int factoryId = System.identityHashCode(beanFactory);
		if (this.factoriesPostProcessed.contains(factoryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + beanFactory);
		}
		this.factoriesPostProcessed.add(factoryId);
		if (!this.registriesPostProcessed.contains(factoryId)) {//未注册处理过的
			// BeanDefinitionRegistryPostProcessor hook apparently not supported...
			// Simply call processConfigurationClasses lazily at this point then.
			processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
		}
		//增强配置类
		enhanceConfigurationClasses(beanFactory);
		beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));//添加后置处理器
	}

ConfigurationClassPostProcessor los enhanceConfigurationClasses extracto de granos de configuración definidos

En primer lugar, la configuración será primero beandefinirlo son adquiridos, de acuerdo con ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTElos atributos se establecerá si la clase es un atributo de configuración fullo lite. Aquí hay que señalar que si frente a una costumbre BeanDefinitionRegistryPostProcessorque se crea extensión, que crearía las clases de configuración, en el que habrá una pronta.

		Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
		for (String beanName : beanFactory.getBeanDefinitionNames()) {
			BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
			Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);//获取配置属性
			MethodMetadata methodMetadata = null;
			if (beanDef instanceof AnnotatedBeanDefinition) {
				methodMetadata = ((AnnotatedBeanDefinition) beanDef).getFactoryMethodMetadata();
			}
			if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {
				// Configuration class (full or lite) or a configuration-derived @Bean method
				// -> resolve bean class at this point...
				AbstractBeanDefinition abd = (AbstractBeanDefinition) beanDef;
				if (!abd.hasBeanClass()) {
					try {//bean注解的方法设置类加载器
						abd.resolveBeanClass(this.beanClassLoader);
					}
					catch (Throwable ex) {
						throw new IllegalStateException(
								"Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
					}
				}
			}//这里就是前面的full 跟 lite的用处了,full可以做增强
			if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
				if (!(beanDef instanceof AbstractBeanDefinition)) {
					throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
							beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
				}//已经存在单例了,就不能增强了
				else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
					logger.info("Cannot enhance @Configuration bean definition '" + beanName +
							"' since its singleton instance has been created too early. The typical cause " +
							"is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
							"return type: Consider declaring such methods as 'static'.");
				}
				configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
			}
		}
		if (configBeanDefs.isEmpty()) {//没有要增强的配置bean直接返回
			// nothing to enhance -> return immediately
			return;
		}

ConfigurationClassPostProcessor de enhanceConfigurationClasses mejorada

Crear un refuerzo clase de configuración ConfigurationClassEnhancer, atravesará la configuración beandefinición del agente para obtener la clase de destino, y luego el agente para mejorar, devolver la clase de proxy, y luego beandefinir los BeanClassajustes para la clase de proxy, se crea esta vez detrás de la creación de la clase de proxy.

		ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
		for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
			AbstractBeanDefinition beanDef = entry.getValue();
			// If a @Configuration class gets proxied, always proxy the target class设置代理目标类属性
			beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
			// Set enhanced subclass of the user-specified bean class
			Class<?> configClass = beanDef.getBeanClass();//获取代理的目标类
			Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);//进行代理
			if (configClass != enhancedClass) {
				if (logger.isTraceEnabled()) {
					logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
							"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
				}
				beanDef.setBeanClass(enhancedClass);//设置为CGLIB动态代理后的类
			}
		}

ConfigurationClassEnhancer de mejora potenciador

En primer lugar determinar la clase de destino no es un EnhancedConfigurationtipo, y si es así explicación se ha mejorado también, porque springcon CGLIBhereda mejorada cuando la clase de objetivo, implementar EnhancedConfigurationla interfaz, es en realidad BeanFactoryAwarela interfaz. Si no hubiera mejorado newEnhancerpara crear una dosis de refuerzo, y luego createClasscrear una clase mejorada.

public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
		if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {//如果已经是EnhancedConfiguration,已经被代理过了
			if (logger.isDebugEnabled()) {
				logger.debug(String.format("Ignoring request to enhance %s as it has " +
						"already been enhanced. This usually indicates that more than one " +
						"ConfigurationClassPostProcessor has been registered (e.g. via " +
						"<context:annotation-config>). This is harmless, but you may " +
						"want check your configuration and remove one CCPP if possible",
						configClass.getName()));
			}
			return configClass;
		}
		Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));//进行动态代理
		if (logger.isTraceEnabled()) {
			logger.trace(String.format("Successfully enhanced %s; enhanced class name is: %s",
					configClass.getName(), enhancedClass.getName()));
		}
		return enhancedClass;
	}

ConfigurationClassEnhancer de newEnhancer crear intensificador

Se trata de CGLIBun refuerzo, para establecer la clase padre, establecer la interfaz, que se EnhancedConfigurationestablece a continuación estrategia de generación, configurar un filtro.

	private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(configSuperClass);//设置父类
		enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});//设置要实现的接口,就是BeanFactoryAware
		enhancer.setUseFactory(false);
		enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
		enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));//生成策略
		enhancer.setCallbackFilter(CALLBACK_FILTER);//过滤器拦截器
		enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());//过滤器类型
		return enhancer;
	}
filtro CALLBACK_FILTER

De hecho, algunos de los interceptor, el método utilizado para hacer para interceptar, por lo tanto mejorado.

	private static final Callback[] CALLBACKS = new Callback[] {
			new BeanMethodInterceptor(),
			new BeanFactoryAwareMethodInterceptor(),
			NoOp.INSTANCE
	};
	private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
estrategia de generación de BeanFactoryAwareGeneratorStrategy

Es la manera de generar los archivos de código de bytes para ver sus propias extensiones a la clase de proxy generada, tal como es, esto generará una propiedad $$beanFactory, y luego usar el método en el que el interceptor.
Aquí Insertar imagen Descripción
De hecho, es hacer que springla beanFactoryclase de configuración del enfoque participativo del proceso de aplicación, en concreto va a decir que lo que es el uso.

ConfigurationClassEnhancer de createClass crear una clase de proxy

Crear una clase de proxy, sin la creación de instancias, y luego registrar el filtro, que es un CGLIBproceso de generación de código de bytes complejo.

	private Class<?> createClass(Enhancer enhancer) {
		Class<?> subclass = enhancer.createClass();
		// Registering callbacks statically (as opposed to thread-local)
		// is critical for usage in an OSGi environment (SPR-5932)...
		Enhancer.registerStaticCallbacks(subclass, CALLBACKS);//注册回调
		return subclass;
	}

Podemos ver el medio de un proceso que genera beanFactorycódigo de bytes atributos:
Aquí Insertar imagen Descripción
este último una escapada de nuestra propia para simular springcómo el uso cglibpara generar proxy dinámico ella.

Pues bien, hoy aquí, esperamos estudio ayuda y entender, no rocíe el Gran Dios ver, comprender solamente su propio aprendizaje, capacidad limitada, por favor excusa.

Publicados 235 artículos originales · ganado elogios 74 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/wangwei19871103/article/details/105008498
Recomendado
Clasificación