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;
});
}
}
}
Aggregations