Search in sources :

Example 1 with Replaces

use of io.micronaut.context.annotation.Replaces in project micronaut-core by micronaut-projects.

the class DefaultBeanContext method filterReplacedBeans.

private <T> void filterReplacedBeans(BeanResolutionContext resolutionContext, Collection<? extends BeanType<T>> candidates) {
    if (candidates.size() > 1) {
        List<BeanType<T>> replacementTypes = new ArrayList<>(2);
        for (BeanType<T> candidate : candidates) {
            if (candidate.getAnnotationMetadata().hasStereotype(REPLACES_ANN)) {
                replacementTypes.add(candidate);
            }
        }
        if (!replacementTypes.isEmpty()) {
            candidates.removeIf(definition -> {
                if (!definition.isEnabled(this, resolutionContext)) {
                    return true;
                }
                final AnnotationMetadata annotationMetadata = definition.getAnnotationMetadata();
                if (annotationMetadata.hasDeclaredStereotype(Infrastructure.class)) {
                    return false;
                }
                Optional<Class<?>> declaringType = Optional.empty();
                if (definition instanceof BeanDefinition) {
                    declaringType = ((BeanDefinition<?>) definition).getDeclaringType();
                }
                Function<Class, Boolean> comparisonFunction = null;
                for (BeanType<T> replacingCandidate : replacementTypes) {
                    if (definition == replacingCandidate) {
                        // don't replace yourself
                        continue;
                    }
                    if (replacingCandidate instanceof ProxyBeanDefinition && ((ProxyBeanDefinition<T>) replacingCandidate).getTargetDefinitionType() == definition.getClass()) {
                        continue;
                    }
                    final AnnotationValue<Replaces> replacesAnn = replacingCandidate.getAnnotation(Replaces.class);
                    Class beanType = replacesAnn.classValue().orElse(getCanonicalBeanType(replacingCandidate));
                    if (replacesAnn.contains(NAMED_MEMBER)) {
                        final String qualifier = replacesAnn.stringValue(NAMED_MEMBER).orElse(null);
                        if (qualifier != null) {
                            final Optional qualified = Qualifiers.<T>byName(qualifier).qualify(beanType, Stream.of(definition));
                            if (qualified.isPresent()) {
                                return true;
                            }
                            continue;
                        }
                    }
                    Optional<Class<?>> factory = replacesAnn.classValue("factory");
                    if (LOG.isDebugEnabled()) {
                        if (factory.isPresent()) {
                            LOG.debug("Bean [{}] replaces existing bean of type [{}] in factory type [{}]", replacingCandidate.getBeanType(), beanType, factory.get());
                        } else {
                            LOG.debug("Bean [{}] replaces existing bean of type [{}]", replacingCandidate.getBeanType(), beanType);
                        }
                    }
                    if (comparisonFunction == null) {
                        comparisonFunction = typeMatches(definition, annotationMetadata);
                    }
                    if (factory.isPresent() && declaringType.isPresent()) {
                        if (factory.get() == declaringType.get()) {
                            if (comparisonFunction.apply(beanType)) {
                                return true;
                            }
                        }
                    } else {
                        if (comparisonFunction.apply(beanType)) {
                            return true;
                        }
                    }
                }
                return false;
            });
        }
    }
}
Also used : Optional(java.util.Optional) ArrayList(java.util.ArrayList) Replaces(io.micronaut.context.annotation.Replaces) ProxyBeanDefinition(io.micronaut.inject.ProxyBeanDefinition) BeanDefinition(io.micronaut.inject.BeanDefinition) ValidatedBeanDefinition(io.micronaut.inject.ValidatedBeanDefinition) DisposableBeanDefinition(io.micronaut.inject.DisposableBeanDefinition) InitializingBeanDefinition(io.micronaut.inject.InitializingBeanDefinition) AnnotationMetadata(io.micronaut.core.annotation.AnnotationMetadata) ProxyBeanDefinition(io.micronaut.inject.ProxyBeanDefinition) AdvisedBeanType(io.micronaut.inject.AdvisedBeanType) BeanType(io.micronaut.inject.BeanType) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Aggregations

Replaces (io.micronaut.context.annotation.Replaces)1 AnnotationMetadata (io.micronaut.core.annotation.AnnotationMetadata)1 AdvisedBeanType (io.micronaut.inject.AdvisedBeanType)1 BeanDefinition (io.micronaut.inject.BeanDefinition)1 BeanType (io.micronaut.inject.BeanType)1 DisposableBeanDefinition (io.micronaut.inject.DisposableBeanDefinition)1 InitializingBeanDefinition (io.micronaut.inject.InitializingBeanDefinition)1 ProxyBeanDefinition (io.micronaut.inject.ProxyBeanDefinition)1 ValidatedBeanDefinition (io.micronaut.inject.ValidatedBeanDefinition)1 ArrayList (java.util.ArrayList)1 Optional (java.util.Optional)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1