Search in sources :

Example 1 with AutowireCandidateQualifier

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

the class QualifierAnnotationAutowireCandidateResolver method checkQualifier.

/**
 * Match the given qualifier annotation against the candidate bean holder.
 */
protected boolean checkQualifier(BeanDefinitionHolder bdHolder, Annotation annotation, SimpleTypeConverter typeConverter) {
    Class<? extends Annotation> type = annotation.annotationType();
    RootBeanDefinition bd = (RootBeanDefinition) bdHolder.getBeanDefinition();
    AutowireCandidateQualifier qualifier = bd.getQualifier(type.getName());
    if (qualifier == null) {
        qualifier = bd.getQualifier(ClassUtils.getShortName(type));
    }
    if (qualifier == null) {
        // First, check annotation on qualified element, if any
        Annotation targetAnnotation = getQualifiedElementAnnotation(bd, type);
        // Then, check annotation on factory method, if applicable
        if (targetAnnotation == null) {
            targetAnnotation = getFactoryMethodAnnotation(bd, type);
        }
        if (targetAnnotation == null) {
            RootBeanDefinition dbd = getResolvedDecoratedDefinition(bd);
            if (dbd != null) {
                targetAnnotation = getFactoryMethodAnnotation(dbd, type);
            }
        }
        if (targetAnnotation == null) {
            // Look for matching annotation on the target class
            if (getBeanFactory() != null) {
                try {
                    Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
                    if (beanType != null) {
                        targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
                    }
                } catch (NoSuchBeanDefinitionException ex) {
                // Not the usual case - simply forget about the type check...
                }
            }
            if (targetAnnotation == null && bd.hasBeanClass()) {
                targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(bd.getBeanClass()), type);
            }
        }
        if (targetAnnotation != null && targetAnnotation.equals(annotation)) {
            return true;
        }
    }
    Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(annotation);
    if (attributes.isEmpty() && qualifier == null) {
        // If no attributes, the qualifier must be present
        return false;
    }
    for (Map.Entry<String, Object> entry : attributes.entrySet()) {
        String attributeName = entry.getKey();
        Object expectedValue = entry.getValue();
        Object actualValue = null;
        // Check qualifier first
        if (qualifier != null) {
            actualValue = qualifier.getAttribute(attributeName);
        }
        if (actualValue == null) {
            // Fall back on bean definition attribute
            actualValue = bd.getAttribute(attributeName);
        }
        if (actualValue == null && attributeName.equals(AutowireCandidateQualifier.VALUE_KEY) && expectedValue instanceof String && bdHolder.matchesName((String) expectedValue)) {
            // Fall back on bean name (or alias) match
            continue;
        }
        if (actualValue == null && qualifier != null) {
            // Fall back on default, but only if the qualifier is present
            actualValue = AnnotationUtils.getDefaultValue(annotation, attributeName);
        }
        if (actualValue != null) {
            actualValue = typeConverter.convertIfNecessary(actualValue, expectedValue.getClass());
        }
        if (!expectedValue.equals(actualValue)) {
            return false;
        }
    }
    return true;
}
Also used : RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) NoSuchBeanDefinitionException(cn.taketoday.beans.factory.NoSuchBeanDefinitionException) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) Map(java.util.Map) Annotation(java.lang.annotation.Annotation)

Example 2 with AutowireCandidateQualifier

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

the class StandardDependenciesBeanPostProcessorTests method testObjectFactoryQualifierInjection.

@Test
public void testObjectFactoryQualifierInjection() {
    bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(SupplierQualifierInjectionBean.class));
    RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
    bd.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "testBean"));
    bf.registerBeanDefinition("dependencyBean", bd);
    bf.registerBeanDefinition("dependencyBean2", new RootBeanDefinition(TestBean.class));
    SupplierQualifierInjectionBean bean = (SupplierQualifierInjectionBean) bf.getBean("annotatedBean");
    assertThat(bean.getTestBean()).isSameAs(bf.getBean("dependencyBean"));
}
Also used : IndexedTestBean(cn.taketoday.beans.testfixture.beans.IndexedTestBean) NestedTestBean(cn.taketoday.beans.testfixture.beans.NestedTestBean) ITestBean(cn.taketoday.beans.testfixture.beans.ITestBean) TestBean(cn.taketoday.beans.testfixture.beans.TestBean) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) Test(org.junit.jupiter.api.Test)

Example 3 with AutowireCandidateQualifier

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

the class InjectAnnotationBeanPostProcessorTests method testObjectFactoryQualifierInjection.

@Test
public void testObjectFactoryQualifierInjection() {
    bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ObjectFactoryQualifierFieldInjectionBean.class));
    RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
    bd.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "testBean"));
    bf.registerBeanDefinition("testBean", bd);
    ObjectFactoryQualifierFieldInjectionBean bean = (ObjectFactoryQualifierFieldInjectionBean) bf.getBean("annotatedBean");
    assertThat(bean.getTestBean()).isSameAs(bf.getBean("testBean"));
}
Also used : RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) Test(org.junit.jupiter.api.Test)

Example 4 with AutowireCandidateQualifier

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

the class InjectAnnotationBeanPostProcessorTests method testObjectFactoryMethodInjectionIntoPrototypeBean.

@Test
public void testObjectFactoryMethodInjectionIntoPrototypeBean() {
    RootBeanDefinition annotatedBeanDefinition = new RootBeanDefinition(ObjectFactoryQualifierMethodInjectionBean.class);
    annotatedBeanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
    bf.registerBeanDefinition("annotatedBean", annotatedBeanDefinition);
    RootBeanDefinition bd = new RootBeanDefinition(TestBean.class);
    bd.addQualifier(new AutowireCandidateQualifier(Qualifier.class, "testBean"));
    bf.registerBeanDefinition("testBean", bd);
    bf.registerBeanDefinition("testBean2", new RootBeanDefinition(TestBean.class));
    ObjectFactoryQualifierMethodInjectionBean bean = (ObjectFactoryQualifierMethodInjectionBean) bf.getBean("annotatedBean");
    assertThat(bean.getTestBean()).isSameAs(bf.getBean("testBean"));
    ObjectFactoryQualifierMethodInjectionBean anotherBean = (ObjectFactoryQualifierMethodInjectionBean) bf.getBean("annotatedBean");
    assertThat(bean).isNotSameAs(anotherBean);
    assertThat(bean.getTestBean()).isSameAs(bf.getBean("testBean"));
}
Also used : NestedTestBean(cn.taketoday.beans.testfixture.beans.NestedTestBean) ITestBean(cn.taketoday.beans.testfixture.beans.ITestBean) IndexedTestBean(cn.taketoday.beans.testfixture.beans.IndexedTestBean) TestBean(cn.taketoday.beans.testfixture.beans.TestBean) RootBeanDefinition(cn.taketoday.beans.factory.support.RootBeanDefinition) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier) Test(org.junit.jupiter.api.Test)

Example 5 with AutowireCandidateQualifier

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

the class AnnotatedBeanDefinitionReader method doRegisterBean.

/**
 * Register a bean from the given bean class, deriving its metadata from
 * class-declared annotations.
 *
 * @param beanClass the class of the bean
 * @param name an explicit name for the bean
 * @param qualifiers specific qualifier annotations to consider, if any,
 * in addition to qualifiers at the bean class level
 * @param supplier a callback for creating an instance of the bean
 * (may be {@code null})
 * @param customizers one or more callbacks for customizing the factory's
 * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
 */
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier, @Nullable BeanDefinitionCustomizer[] customizers) {
    AnnotatedGenericBeanDefinition definition = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(definition.getMetadata())) {
        return;
    }
    definition.setInstanceSupplier(supplier);
    ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(definition);
    definition.setScope(scopeMetadata.getScopeName());
    String beanName = name != null ? name : beanNameGenerator.generateBeanName(definition, registry);
    AnnotationConfigUtils.processCommonDefinitionAnnotations(definition);
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
            if (Primary.class == qualifier) {
                definition.setPrimary(true);
            } else if (Lazy.class == qualifier) {
                definition.setLazyInit(true);
            } else {
                definition.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    applyDynamicCustomizers(definition, customizers);
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(definition, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
Also used : ScopeMetadata(cn.taketoday.context.loader.ScopeMetadata) BeanDefinitionHolder(cn.taketoday.beans.factory.config.BeanDefinitionHolder) AnnotatedGenericBeanDefinition(cn.taketoday.beans.factory.annotation.AnnotatedGenericBeanDefinition) AutowireCandidateQualifier(cn.taketoday.beans.factory.support.AutowireCandidateQualifier)

Aggregations

AutowireCandidateQualifier (cn.taketoday.beans.factory.support.AutowireCandidateQualifier)17 RootBeanDefinition (cn.taketoday.beans.factory.support.RootBeanDefinition)15 Test (org.junit.jupiter.api.Test)12 ITestBean (cn.taketoday.beans.testfixture.beans.ITestBean)10 IndexedTestBean (cn.taketoday.beans.testfixture.beans.IndexedTestBean)10 NestedTestBean (cn.taketoday.beans.testfixture.beans.NestedTestBean)10 TestBean (cn.taketoday.beans.testfixture.beans.TestBean)10 NoSuchBeanDefinitionException (cn.taketoday.beans.factory.NoSuchBeanDefinitionException)3 Annotation (java.lang.annotation.Annotation)3 Map (java.util.Map)3 AnnotatedGenericBeanDefinition (cn.taketoday.beans.factory.annotation.AnnotatedGenericBeanDefinition)2 BeanDefinitionHolder (cn.taketoday.beans.factory.config.BeanDefinitionHolder)2 ScopeMetadata (cn.taketoday.context.loader.ScopeMetadata)2