use of cn.taketoday.beans.BeansException in project today-infrastructure by TAKETODAY.
the class ConstructorResolver method createArgumentArray.
/**
* Create an array of arguments to invoke a constructor or factory method,
* given the resolved constructor argument values.
*/
private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition merged, @Nullable ConstructorArgumentValues resolvedValues, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable, BeanWrapper wrapper, boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = customConverter != null ? customConverter : wrapper;
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
HashSet<ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
LinkedHashSet<String> autowiredBeanNames = new LinkedHashSet<>(4);
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = paramNames != null ? paramNames[paramIndex] : "";
// Try to find matching constructor argument value, either indexed or generic.
ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// it could match after type conversion (for example, String -> int).
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
usedValueHolders.add(valueHolder);
Object originalValue = valueHolder.getValue();
Object convertedValue;
if (valueHolder.isConverted()) {
convertedValue = valueHolder.getConvertedValue();
args.preparedArguments[paramIndex] = convertedValue;
} else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
} catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(merged.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(valueHolder.getValue()) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ValueHolder) {
Object sourceValue = ((ValueHolder) sourceHolder).getValue();
args.resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
} else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(merged.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?");
}
try {
Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter, fallback);
args.resolveNecessary = true;
args.arguments[paramIndex] = autowiredArgument;
args.rawArguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(merged.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
for (String autowiredBeanName : autowiredBeanNames) {
beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (log.isDebugEnabled()) {
log.debug("Autowiring by type from bean name '{}' via {} to bean named '{}'", beanName, (executable instanceof Constructor ? "constructor" : "factory method"), autowiredBeanName);
}
}
return args;
}
use of cn.taketoday.beans.BeansException in project today-infrastructure by TAKETODAY.
the class TestContextTransactionUtils method retrieveDataSource.
/**
* Retrieve the {@link DataSource} to use for the supplied {@linkplain TestContext
* test context}.
* <p>The following algorithm is used to retrieve the {@code DataSource} from
* the {@link cn.taketoday.context.ApplicationContext ApplicationContext}
* of the supplied test context:
* <ol>
* <li>Look up the {@code DataSource} by type and name, if the supplied
* {@code name} is non-empty, throwing a {@link BeansException} if the named
* {@code DataSource} does not exist.
* <li>Attempt to look up the single {@code DataSource} by type.
* <li>Attempt to look up the <em>primary</em> {@code DataSource} by type.
* <li>Attempt to look up the {@code DataSource} by type and the
* {@linkplain #DEFAULT_DATA_SOURCE_NAME default data source name}.
* </ol>
*
* @param testContext the test context for which the {@code DataSource}
* should be retrieved; never {@code null}
* @param name the name of the {@code DataSource} to retrieve
* (may be {@code null} or <em>empty</em>)
* @return the {@code DataSource} to use, or {@code null} if not found
* @throws BeansException if an error occurs while retrieving an explicitly
* named {@code DataSource}
*/
@Nullable
public static DataSource retrieveDataSource(TestContext testContext, @Nullable String name) {
Assert.notNull(testContext, "TestContext must not be null");
BeanFactory bf = testContext.getApplicationContext().getAutowireCapableBeanFactory();
try {
// Look up by type and explicit name
if (StringUtils.hasText(name)) {
return bf.getBean(name, DataSource.class);
}
} catch (BeansException ex) {
logger.error(String.format("Failed to retrieve DataSource named '%s' for test context %s", name, testContext), ex);
throw ex;
}
try {
// Look up single bean by type
Map<String, DataSource> dataSources = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, DataSource.class);
if (dataSources.size() == 1) {
return dataSources.values().iterator().next();
}
try {
// look up single bean by type, with support for 'primary' beans
return bf.getBean(DataSource.class);
} catch (BeansException ex) {
logBeansException(testContext, ex, PlatformTransactionManager.class);
}
// look up by type and default name
return bf.getBean(DEFAULT_DATA_SOURCE_NAME, DataSource.class);
} catch (BeansException ex) {
logBeansException(testContext, ex, DataSource.class);
return null;
}
}
use of cn.taketoday.beans.BeansException in project today-framework by TAKETODAY.
the class TestContextTransactionUtils method retrieveDataSource.
/**
* Retrieve the {@link DataSource} to use for the supplied {@linkplain TestContext
* test context}.
* <p>The following algorithm is used to retrieve the {@code DataSource} from
* the {@link cn.taketoday.context.ApplicationContext ApplicationContext}
* of the supplied test context:
* <ol>
* <li>Look up the {@code DataSource} by type and name, if the supplied
* {@code name} is non-empty, throwing a {@link BeansException} if the named
* {@code DataSource} does not exist.
* <li>Attempt to look up the single {@code DataSource} by type.
* <li>Attempt to look up the <em>primary</em> {@code DataSource} by type.
* <li>Attempt to look up the {@code DataSource} by type and the
* {@linkplain #DEFAULT_DATA_SOURCE_NAME default data source name}.
* </ol>
*
* @param testContext the test context for which the {@code DataSource}
* should be retrieved; never {@code null}
* @param name the name of the {@code DataSource} to retrieve
* (may be {@code null} or <em>empty</em>)
* @return the {@code DataSource} to use, or {@code null} if not found
* @throws BeansException if an error occurs while retrieving an explicitly
* named {@code DataSource}
*/
@Nullable
public static DataSource retrieveDataSource(TestContext testContext, @Nullable String name) {
Assert.notNull(testContext, "TestContext must not be null");
BeanFactory bf = testContext.getApplicationContext().getAutowireCapableBeanFactory();
try {
// Look up by type and explicit name
if (StringUtils.hasText(name)) {
return bf.getBean(name, DataSource.class);
}
} catch (BeansException ex) {
logger.error(String.format("Failed to retrieve DataSource named '%s' for test context %s", name, testContext), ex);
throw ex;
}
try {
// Look up single bean by type
Map<String, DataSource> dataSources = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, DataSource.class);
if (dataSources.size() == 1) {
return dataSources.values().iterator().next();
}
try {
// look up single bean by type, with support for 'primary' beans
return bf.getBean(DataSource.class);
} catch (BeansException ex) {
logBeansException(testContext, ex, PlatformTransactionManager.class);
}
// look up by type and default name
return bf.getBean(DEFAULT_DATA_SOURCE_NAME, DataSource.class);
} catch (BeansException ex) {
logBeansException(testContext, ex, DataSource.class);
return null;
}
}
use of cn.taketoday.beans.BeansException in project today-framework by TAKETODAY.
the class XmlListableBeanFactoryTests method setup.
@BeforeEach
public void setup() {
parent = new StandardBeanFactory();
Map map = new HashMap();
map.put("name", "Albert");
RootBeanDefinition bd1 = new RootBeanDefinition(TestBean.class);
bd1.setPropertyValues(new PropertyValues(map));
parent.registerBeanDefinition("father", bd1);
map = new HashMap();
map.put("name", "Roderick");
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
bd2.setPropertyValues(new PropertyValues(map));
parent.registerBeanDefinition("rod", bd2);
this.factory = new StandardBeanFactory(parent);
new XmlBeanDefinitionReader(this.factory).loadBeanDefinitions(new ClassPathResource("test.xml", getClass()));
this.factory.addBeanPostProcessor(new InitializationBeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
if (bean instanceof TestBean) {
((TestBean) bean).setPostProcessed(true);
}
if (bean instanceof DummyFactory) {
((DummyFactory) bean).setPostProcessed(true);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
return bean;
}
});
this.factory.addBeanPostProcessor(new LifecycleBean.PostProcessor());
this.factory.addBeanPostProcessor(new ProtectedLifecycleBean.PostProcessor());
// this.factory.preInstantiateSingletons();
}
use of cn.taketoday.beans.BeansException in project today-framework by TAKETODAY.
the class ConstructorResolver method createArgumentArray.
/**
* Create an array of arguments to invoke a constructor or factory method,
* given the resolved constructor argument values.
*/
private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition merged, @Nullable ConstructorArgumentValues resolvedValues, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable, BeanWrapper wrapper, boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = customConverter != null ? customConverter : wrapper;
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
HashSet<ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
LinkedHashSet<String> autowiredBeanNames = new LinkedHashSet<>(4);
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = paramNames != null ? paramNames[paramIndex] : "";
// Try to find matching constructor argument value, either indexed or generic.
ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// it could match after type conversion (for example, String -> int).
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
usedValueHolders.add(valueHolder);
Object originalValue = valueHolder.getValue();
Object convertedValue;
if (valueHolder.isConverted()) {
convertedValue = valueHolder.getConvertedValue();
args.preparedArguments[paramIndex] = convertedValue;
} else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
} catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(merged.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(valueHolder.getValue()) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ValueHolder) {
Object sourceValue = ((ValueHolder) sourceHolder).getValue();
args.resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
} else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(merged.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Ambiguous argument values for parameter of type [" + paramType.getName() + "] - did you specify the correct bean references as arguments?");
}
try {
Object autowiredArgument = resolveAutowiredArgument(methodParam, beanName, autowiredBeanNames, converter, fallback);
args.resolveNecessary = true;
args.arguments[paramIndex] = autowiredArgument;
args.rawArguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(merged.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
for (String autowiredBeanName : autowiredBeanNames) {
beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (log.isDebugEnabled()) {
log.debug("Autowiring by type from bean name '{}' via {} to bean named '{}'", beanName, (executable instanceof Constructor ? "constructor" : "factory method"), autowiredBeanName);
}
}
return args;
}
Aggregations