Search in sources :

Example 1 with AbstractBeanDefinition

use of cn.taketoday.beans.factory.support.AbstractBeanDefinition in project today-infrastructure by TAKETODAY.

the class ScopedProxyUtils method createScopedProxy.

/**
 * Generate a scoped proxy for the supplied target bean, registering the target
 * bean with an internal name and setting 'targetBeanName' on the scoped proxy.
 *
 * @param definition the original bean definition
 * @param registry the bean definition registry
 * @param proxyTargetClass whether to create a target class proxy
 * @return the scoped proxy definition
 * @see #getTargetBeanName(String)
 * @see #getOriginalBeanName(String)
 */
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
    String originalBeanName = definition.getBeanName();
    BeanDefinition targetDefinition = definition.getBeanDefinition();
    String targetBeanName = getTargetBeanName(originalBeanName);
    // Create a scoped proxy definition for the original bean name,
    // "hiding" the target bean in an internal target definition.
    RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
    proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
    proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
    proxyDefinition.setSource(definition.getSource());
    proxyDefinition.setRole(targetDefinition.getRole());
    proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
    if (proxyTargetClass) {
        targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
    // ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
    } else {
        proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
    }
    // Copy autowire settings from original bean definition.
    proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
    proxyDefinition.setPrimary(targetDefinition.isPrimary());
    if (targetDefinition instanceof AbstractBeanDefinition) {
        proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
    }
    // The target bean should be ignored in favor of the scoped proxy.
    targetDefinition.setAutowireCandidate(false);
    targetDefinition.setPrimary(false);
    // Register the target bean as separate bean in the factory.
    registry.registerBeanDefinition(targetBeanName, targetDefinition);
    // (potentially an inner bean).
    return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}
Also used : AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition) BeanDefinitionHolder(cn.taketoday.beans.factory.config.BeanDefinitionHolder) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) BeanDefinition(cn.taketoday.beans.factory.config.BeanDefinition) AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition)

Example 2 with AbstractBeanDefinition

use of cn.taketoday.beans.factory.support.AbstractBeanDefinition in project today-infrastructure by TAKETODAY.

the class AbstractInterceptorDrivenBeanDefinitionDecorator method decorate.

@Override
public final BeanDefinitionHolder decorate(@NonNull Node node, BeanDefinitionHolder definitionHolder, ParserContext parserContext) {
    BeanDefinitionRegistry registry = parserContext.getRegistry();
    // get the root bean name - will be the name of the generated proxy factory bean
    String existingBeanName = definitionHolder.getBeanName();
    BeanDefinition targetDefinition = definitionHolder.getBeanDefinition();
    BeanDefinitionHolder targetHolder = new BeanDefinitionHolder(targetDefinition, existingBeanName + ".TARGET");
    // delegate to subclass for interceptor definition
    BeanDefinition interceptorDefinition = createInterceptorDefinition(node);
    // generate name and register the interceptor
    String interceptorName = existingBeanName + '.' + getInterceptorNameSuffix(interceptorDefinition);
    BeanDefinitionReaderUtils.registerBeanDefinition(new BeanDefinitionHolder(interceptorDefinition, interceptorName), registry);
    BeanDefinitionHolder result = definitionHolder;
    if (!isProxyFactoryBeanDefinition(targetDefinition)) {
        // create the proxy definition
        RootBeanDefinition proxyDefinition = new RootBeanDefinition();
        // create proxy factory bean definition
        proxyDefinition.setBeanClass(ProxyFactoryBean.class);
        proxyDefinition.setScope(targetDefinition.getScope());
        proxyDefinition.setLazyInit(targetDefinition.isLazyInit());
        // set the target
        proxyDefinition.setDecoratedDefinition(targetHolder);
        proxyDefinition.getPropertyValues().add("target", targetHolder);
        // create the interceptor names list
        proxyDefinition.getPropertyValues().add("interceptorNames", new ManagedList<String>());
        // copy autowire settings from original bean definition.
        proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
        proxyDefinition.setPrimary(targetDefinition.isPrimary());
        if (targetDefinition instanceof AbstractBeanDefinition) {
            proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
        }
        // wrap it in a BeanDefinitionHolder with bean name
        result = new BeanDefinitionHolder(proxyDefinition, existingBeanName);
    }
    addInterceptorNameToList(interceptorName, result.getBeanDefinition());
    return result;
}
Also used : AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition) BeanDefinitionHolder(cn.taketoday.beans.factory.config.BeanDefinitionHolder) BeanDefinitionRegistry(cn.taketoday.beans.factory.support.BeanDefinitionRegistry) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) BeanDefinition(cn.taketoday.beans.factory.config.BeanDefinition) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition)

Example 3 with AbstractBeanDefinition

use of cn.taketoday.beans.factory.support.AbstractBeanDefinition in project today-infrastructure by TAKETODAY.

the class ClassPathMapperScanner method postProcessBeanDefinition.

protected BeanDefinitionHolder postProcessBeanDefinition(BeanDefinitionHolder holder) {
    AbstractBeanDefinition definition = (AbstractBeanDefinition) holder.getBeanDefinition();
    boolean scopedProxy = false;
    if (ScopedProxyFactoryBean.class.getName().equals(definition.getBeanClassName())) {
        definition = (AbstractBeanDefinition) Optional.ofNullable(((RootBeanDefinition) definition).getDecoratedDefinition()).map(BeanDefinitionHolder::getBeanDefinition).orElseThrow(() -> new IllegalStateException("The target bean definition of scoped proxy bean not found. Root bean definition[" + holder + "]"));
        scopedProxy = true;
    }
    String beanClassName = definition.getBeanClassName();
    log.debug("Creating MapperFactoryBean with name '{}' and '{}' mapperInterface", holder.getBeanName(), beanClassName);
    // the mapper interface is the original class of the bean
    // but, the actual class of the bean is MapperFactoryBean
    // issue #59
    definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
    definition.setBeanClass(mapperFactoryBeanClass);
    PropertyValues propertyValues = definition.getPropertyValues();
    propertyValues.add("addToConfig", addToConfig);
    propertyValues.add("mapperInterface", beanClassName);
    // Attribute for MockitoPostProcessor
    // https://github.com/mybatis/spring-boot-starter/issues/475
    definition.setAttribute(FACTORY_BEAN_OBJECT_TYPE, beanClassName);
    boolean explicitFactoryUsed = false;
    if (StringUtils.hasText(sqlSessionFactoryBeanName)) {
        propertyValues.add("sqlSessionFactory", RuntimeBeanReference.from(sqlSessionFactoryBeanName));
        explicitFactoryUsed = true;
    } else if (sqlSessionFactory != null) {
        propertyValues.add("sqlSessionFactory", sqlSessionFactory);
        explicitFactoryUsed = true;
    }
    if (StringUtils.hasText(sqlSessionTemplateBeanName)) {
        if (explicitFactoryUsed) {
            log.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
        }
        propertyValues.add("sqlSessionTemplate", RuntimeBeanReference.from(sqlSessionTemplateBeanName));
        explicitFactoryUsed = true;
    } else if (sqlSessionTemplate != null) {
        if (explicitFactoryUsed) {
            log.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
        }
        propertyValues.add("sqlSessionTemplate", sqlSessionTemplate);
        explicitFactoryUsed = true;
    }
    if (!explicitFactoryUsed) {
        log.debug("Enabling autowire by type for MapperFactoryBean with name '{}'.", holder.getBeanName());
        definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
    }
    definition.setLazyInit(lazyInitialization);
    if (!scopedProxy) {
        if (BeanDefinition.SCOPE_SINGLETON.equals(definition.getScope()) && defaultScope != null) {
            definition.setScope(defaultScope);
        }
        if (!definition.isSingleton()) {
            BeanDefinitionRegistry registry = delegate.getRegistry();
            return ScopedProxyUtils.createScopedProxy(holder, registry, true);
        }
    }
    return holder;
}
Also used : PropertyValues(cn.taketoday.beans.PropertyValues) AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition) ScopedProxyFactoryBean(cn.taketoday.aop.scope.ScopedProxyFactoryBean) BeanDefinitionRegistry(cn.taketoday.beans.factory.support.BeanDefinitionRegistry)

Example 4 with AbstractBeanDefinition

use of cn.taketoday.beans.factory.support.AbstractBeanDefinition in project today-infrastructure by TAKETODAY.

the class AbstractSingleBeanDefinitionParser method parseInternal.

/**
 * Creates a {@link BeanDefinitionBuilder} instance for the
 * {@link #getBeanClass bean Class} and passes it to the
 * {@link #doParse} strategy method.
 *
 * @param element the element that is to be parsed into a single BeanDefinition
 * @param parserContext the object encapsulating the current state of the parsing process
 * @return the BeanDefinition resulting from the parsing of the supplied {@link Element}
 * @throws IllegalStateException if the bean {@link Class} returned from
 * {@link #getBeanClass(Element)} is {@code null}
 * @see #doParse
 */
@Override
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
    String parentName = getParentName(element);
    if (parentName != null) {
        builder.getRawBeanDefinition().setParentName(parentName);
    }
    Class<?> beanClass = getBeanClass(element);
    if (beanClass != null) {
        builder.getRawBeanDefinition().setBeanClass(beanClass);
    } else {
        String beanClassName = getBeanClassName(element);
        if (beanClassName != null) {
            builder.getRawBeanDefinition().setBeanClassName(beanClassName);
        }
    }
    builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
    BeanDefinition containingBd = parserContext.getContainingBeanDefinition();
    if (containingBd != null) {
        // Inner bean definition must receive same scope as containing bean.
        builder.setScope(containingBd.getScope());
    }
    if (parserContext.isDefaultLazyInit()) {
        // Default-lazy-init applies to custom bean definitions as well.
        builder.setLazyInit(true);
    }
    doParse(element, parserContext, builder);
    return builder.getBeanDefinition();
}
Also used : BeanDefinitionBuilder(cn.taketoday.beans.factory.support.BeanDefinitionBuilder) BeanDefinition(cn.taketoday.beans.factory.config.BeanDefinition) AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition)

Example 5 with AbstractBeanDefinition

use of cn.taketoday.beans.factory.support.AbstractBeanDefinition in project today-infrastructure by TAKETODAY.

the class BeanAnnotationAttributePropagationTests method beanDef.

private AbstractBeanDefinition beanDef(Class<?> configClass) {
    StandardBeanFactory factory = new StandardBeanFactory();
    factory.registerBeanDefinition("config", new RootBeanDefinition(configClass));
    ConfigurationClassPostProcessor pp = new ConfigurationClassPostProcessor();
    pp.postProcessBeanFactory(factory);
    return (AbstractBeanDefinition) factory.getBeanDefinition("foo");
}
Also used : AbstractBeanDefinition(cn.taketoday.beans.factory.support.AbstractBeanDefinition) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) StandardBeanFactory(cn.taketoday.beans.factory.support.StandardBeanFactory) ConfigurationClassPostProcessor(cn.taketoday.context.annotation.ConfigurationClassPostProcessor)

Aggregations

AbstractBeanDefinition (cn.taketoday.beans.factory.support.AbstractBeanDefinition)32 Test (org.junit.jupiter.api.Test)19 StandardBeanFactory (cn.taketoday.beans.factory.support.StandardBeanFactory)12 BeanDefinition (cn.taketoday.beans.factory.config.BeanDefinition)7 BeanDefinitionHolder (cn.taketoday.beans.factory.config.BeanDefinitionHolder)7 RootBeanDefinition (cn.taketoday.beans.factory.support.RootBeanDefinition)7 BeanDefinitionRegistry (cn.taketoday.beans.factory.support.BeanDefinitionRegistry)4 GenericApplicationContext (cn.taketoday.context.support.GenericApplicationContext)4 StandardApplicationContext (cn.taketoday.context.support.StandardApplicationContext)3 ScopedProxyFactoryBean (cn.taketoday.aop.scope.ScopedProxyFactoryBean)2 PropertyValues (cn.taketoday.beans.PropertyValues)2 BeanDefinitionStoreException (cn.taketoday.beans.factory.BeanDefinitionStoreException)2 SimpleThreadScope (cn.taketoday.beans.factory.config.SimpleThreadScope)2 BeanComponentDefinition (cn.taketoday.beans.factory.parsing.BeanComponentDefinition)2 ComponentDefinition (cn.taketoday.beans.factory.parsing.ComponentDefinition)2 BeanDefinitionBuilder (cn.taketoday.beans.factory.support.BeanDefinitionBuilder)2 ConfigurationClassPostProcessor (cn.taketoday.context.annotation.ConfigurationClassPostProcessor)2 ClassPathResource (cn.taketoday.core.io.ClassPathResource)2 Nullable (cn.taketoday.lang.Nullable)2 AutowireCapableBeanFactory (cn.taketoday.beans.factory.config.AutowireCapableBeanFactory)1