Example usage for org.springframework.context.annotation ConfigurationClassEnhancer enhance

List of usage examples for org.springframework.context.annotation ConfigurationClassEnhancer enhance

Introduction

In this page you can find the example usage for org.springframework.context.annotation ConfigurationClassEnhancer enhance.

Prototype

public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) 

Source Link

Document

Loads the specified class and generates a CGLIB subclass of it equipped with container-aware callbacks capable of respecting scoping and other bean semantics.

Usage

From source file:org.springframework.context.annotation.ConfigurationClassPostProcessor.java

/**
 * Post-processes a BeanFactory in search of Configuration class BeanDefinitions;
 * any candidates are then enhanced by a {@link ConfigurationClassEnhancer}.
 * Candidate status is determined by BeanDefinition attribute metadata.
 * @see ConfigurationClassEnhancer//from  w w w .jav  a2  s  .  c  o m
 */
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
    Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
    for (String beanName : beanFactory.getBeanDefinitionNames()) {
        BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
        if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
            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.isWarnEnabled() && beanFactory.containsSingleton(beanName)) {
                logger.warn("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()) {
        // nothing to enhance -> return immediately
        return;
    }

    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);
        try {
            // Set enhanced subclass of the user-specified bean class
            Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
            if (configClass != null) {
                Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
                if (configClass != enhancedClass) {
                    if (logger.isDebugEnabled()) {
                        logger.debug(String.format(
                                "Replacing bean definition '%s' existing class '%s' with "
                                        + "enhanced class '%s'",
                                entry.getKey(), configClass.getName(), enhancedClass.getName()));
                    }
                    beanDef.setBeanClass(enhancedClass);
                }
            }
        } catch (Throwable ex) {
            throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(),
                    ex);
        }
    }
}