5.x primavera Fuente invokeBeanFactoryPostProcessors diez Excursión de tres
- procesador de ejecución BeanFactoryPostProcessor
- Tipo de procesador BeanDefinitionRegistryPostProcessor ejecución
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 BeanDefinitionRegistryPostProcessor
tipo de tratamiento, seguido por una costumbre BeanFactoryPostProcessor
tipo de procesamiento.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//BeanDefinitionRegistryPostProcessor的
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);//自定义的BeanFactoryPostProcessor
Tipo de procesador BeanDefinitionRegistryPostProcessor ejecución
Principalmente ConfigurationClassPostProcessor
de postProcessBeanFactory
, existe la costumbre, nuestra principal preocupación ConfigurationClassPostProcessor
es.
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 ImportAwareBeanPostProcessor
post-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 bean
definirlo son adquiridos, de acuerdo con ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE
los atributos se establecerá si la clase es un atributo de configuración full
o lite
. Aquí hay que señalar que si frente a una costumbre BeanDefinitionRegistryPostProcessor
que 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 bean
definición del agente para obtener la clase de destino, y luego el agente para mejorar, devolver la clase de proxy, y luego bean
definir los BeanClass
ajustes 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 EnhancedConfiguration
tipo, y si es así explicación se ha mejorado también, porque spring
con CGLIB
hereda mejorada cuando la clase de objetivo, implementar EnhancedConfiguration
la interfaz, es en realidad BeanFactoryAware
la interfaz. Si no hubiera mejorado newEnhancer
para crear una dosis de refuerzo, y luego createClass
crear 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 CGLIB
un refuerzo, para establecer la clase padre, establecer la interfaz, que se EnhancedConfiguration
establece 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.
De hecho, es hacer que spring
la beanFactory
clase 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 CGLIB
proceso 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 beanFactory
código de bytes atributos:
este último una escapada de nuestra propia para simular spring
cómo el uso cglib
para 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.