use of io.micronaut.inject.ConstructorInjectionPoint in project micronaut-core by micronaut-projects.
the class DefaultBeanContext method doCreateBean.
/**
* Execution the creation of a bean. The returned value can be null if a
* factory method returned null.
*
* @param resolutionContext The {@link BeanResolutionContext}
* @param beanDefinition The {@link BeanDefinition}
* @param qualifier The {@link Qualifier}
* @param qualifierBeanType The bean type used in the qualifier
* @param isSingleton Whether the bean is a singleton
* @param argumentValues Any argument values passed to create the bean
* @param <T> The bean generic type
* @return The created bean
*/
@Nullable
protected <T> T doCreateBean(@NonNull BeanResolutionContext resolutionContext, @NonNull BeanDefinition<T> beanDefinition, @Nullable Qualifier<T> qualifier, @Nullable Argument<T> qualifierBeanType, boolean isSingleton, @Nullable Map<String, Object> argumentValues) {
if (argumentValues == null) {
argumentValues = Collections.emptyMap();
}
Qualifier<T> declaredQualifier = beanDefinition.getDeclaredQualifier();
Class<T> beanType = beanDefinition.getBeanType();
if (isSingleton) {
BeanRegistration<T> beanRegistration = singletonObjects.get(new BeanKey<>(beanDefinition, declaredQualifier));
final Class<T> beanClass = qualifierBeanType.getType();
if (beanRegistration != null) {
if (qualifier == null || qualifier.reduce(beanClass, Stream.of(beanRegistration.beanDefinition)).findFirst().isPresent()) {
return beanRegistration.bean;
}
} else if (qualifier != null) {
beanRegistration = singletonObjects.get(new BeanKey<>(beanDefinition, null));
if (beanRegistration != null && qualifier.reduce(beanClass, Stream.of(beanRegistration.beanDefinition)).findFirst().isPresent()) {
return beanRegistration.bean;
}
}
}
T bean;
if (beanDefinition instanceof BeanFactory) {
BeanFactory<T> beanFactory = (BeanFactory<T>) beanDefinition;
try {
if (beanFactory instanceof ParametrizedBeanFactory) {
ParametrizedBeanFactory<T> parametrizedBeanFactory = (ParametrizedBeanFactory<T>) beanFactory;
Argument<?>[] requiredArguments = parametrizedBeanFactory.getRequiredArguments();
Map<String, Object> convertedValues = new LinkedHashMap<>(argumentValues);
for (Argument<?> requiredArgument : requiredArguments) {
String argumentName = requiredArgument.getName();
Object val = argumentValues.get(argumentName);
if (val == null && !requiredArgument.isDeclaredNullable()) {
throw new BeanInstantiationException(resolutionContext, "Missing bean argument [" + requiredArgument + "] for type: " + beanType.getName() + ". Required arguments: " + ArrayUtils.toString(requiredArguments));
}
Object convertedValue = null;
if (val != null) {
if (requiredArgument.getType().isInstance(val)) {
convertedValue = val;
} else {
convertedValue = ConversionService.SHARED.convert(val, requiredArgument).orElseThrow(() -> new BeanInstantiationException(resolutionContext, "Invalid bean argument [" + requiredArgument + "]. Cannot convert object [" + val + "] to required type: " + requiredArgument.getType()));
}
}
convertedValues.put(argumentName, convertedValue);
}
bean = parametrizedBeanFactory.build(resolutionContext, this, beanDefinition, convertedValues);
} else {
boolean propagateQualifier = beanDefinition.isProxy() && declaredQualifier instanceof Named;
if (propagateQualifier) {
resolutionContext.setAttribute(BeanDefinition.NAMED_ATTRIBUTE, ((Named) declaredQualifier).getName());
}
resolutionContext.setCurrentQualifier(declaredQualifier != null ? declaredQualifier : qualifier);
try {
bean = beanFactory.build(resolutionContext, this, beanDefinition);
} finally {
resolutionContext.setCurrentQualifier(null);
if (propagateQualifier) {
resolutionContext.removeAttribute(BeanDefinition.NAMED_ATTRIBUTE);
}
}
if (bean == null) {
throw new BeanInstantiationException(resolutionContext, "Bean Factory [" + beanFactory + "] returned null");
} else {
if (bean instanceof Qualified) {
((Qualified) bean).$withBeanQualifier(declaredQualifier);
}
}
}
} catch (Throwable e) {
if (e instanceof DependencyInjectionException) {
throw e;
}
if (e instanceof DisabledBeanException) {
throw e;
}
if (e instanceof BeanInstantiationException) {
throw e;
} else {
if (!resolutionContext.getPath().isEmpty()) {
throw new BeanInstantiationException(resolutionContext, e);
} else {
throw new BeanInstantiationException(beanDefinition, e);
}
}
}
} else {
ConstructorInjectionPoint<T> constructor = beanDefinition.getConstructor();
Argument<?>[] requiredConstructorArguments = constructor.getArguments();
if (requiredConstructorArguments.length == 0) {
bean = constructor.invoke();
} else {
Object[] constructorArgs = new Object[requiredConstructorArguments.length];
for (int i = 0; i < requiredConstructorArguments.length; i++) {
Class<?> argument = requiredConstructorArguments[i].getType();
constructorArgs[i] = getBean(resolutionContext, argument);
}
bean = constructor.invoke(constructorArgs);
}
inject(resolutionContext, null, bean);
}
if (bean != null) {
Qualifier<T> finalQualifier = qualifier != null ? qualifier : declaredQualifier;
if (!(bean instanceof BeanCreatedEventListener) && CollectionUtils.isNotEmpty(beanCreationEventListeners)) {
for (Map.Entry<Class, List<BeanCreatedEventListener>> entry : beanCreationEventListeners) {
if (entry.getKey().isAssignableFrom(beanType)) {
BeanKey<T> beanKey = new BeanKey<>(beanDefinition, finalQualifier);
for (BeanCreatedEventListener<?> listener : entry.getValue()) {
bean = (T) listener.onCreated(new BeanCreatedEvent(this, beanDefinition, beanKey, bean));
if (bean == null) {
throw new BeanInstantiationException(resolutionContext, "Listener [" + listener + "] returned null from onCreated event");
}
}
}
}
}
if (beanDefinition instanceof ValidatedBeanDefinition) {
bean = ((ValidatedBeanDefinition<T>) beanDefinition).validate(resolutionContext, bean);
}
if (LOG_LIFECYCLE.isDebugEnabled()) {
LOG_LIFECYCLE.debug("Created bean [{}] from definition [{}] with qualifier [{}]", bean, beanDefinition, finalQualifier);
}
}
return bean;
}
Aggregations