private String getConsumerDescription(UnsatisfiedDependencyException ex) { InjectionPoint injectionPoint = ex.getInjectionPoint(); if (injectionPoint != null) { if (injectionPoint.getField() != null) { return String.format("Field %s in %s", injectionPoint.getField().getName(), injectionPoint.getField().getDeclaringClass().getName()); } if (injectionPoint.getMethodParameter() != null) { if (injectionPoint.getMethodParameter().getConstructor() != null) { return String.format("Parameter %d of constructor in %s", injectionPoint.getMethodParameter().getParameterIndex(), injectionPoint.getMethodParameter().getDeclaringClass() .getName()); } return String.format("Parameter %d of method %s in %s", injectionPoint.getMethodParameter().getParameterIndex(), injectionPoint.getMethodParameter().getMethod().getName(), injectionPoint.getMethodParameter().getDeclaringClass() .getName()); } } return ex.getResourceDescription(); }
private String getDescription(BeanCreationException ex) { if (StringUtils.hasText(ex.getResourceDescription())) { return String.format(" defined in %s", ex.getResourceDescription()); } InjectionPoint failedInjectionPoint = findFailedInjectionPoint(ex); if (failedInjectionPoint != null && failedInjectionPoint.getField() != null) { return String.format(" (field %s)", failedInjectionPoint.getField()); } return ""; }
@Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @ConditionalOnMissingBean(CircuitBreaker.class) public CircuitBreaker circuitBreaker(final InjectionPoint ip) { FailsafeBreaker annotation = null; for (final Annotation a : ip.getAnnotations()) { if (a instanceof FailsafeBreaker) { annotation = (FailsafeBreaker) a; break; } } return circuitBreakerRegistry.getOrCreate(annotation.value()); }
/** * Resolve the prepared arguments stored in the given bean definition. */ private Object[] resolvePreparedArguments( String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) { Class<?>[] paramTypes = (methodOrCtor instanceof Method ? ((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes()); TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ? this.beanFactory.getCustomTypeConverter() : bw); BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); Object[] resolvedArgs = new Object[argsToResolve.length]; for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) { Object argValue = argsToResolve[argIndex]; MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, argIndex); GenericTypeResolver.resolveParameterType(methodParam, methodOrCtor.getDeclaringClass()); if (argValue instanceof AutowiredArgumentMarker) { argValue = resolveAutowiredArgument(methodParam, beanName, null, converter); } else if (argValue instanceof BeanMetadataElement) { argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue); } else if (argValue instanceof String) { argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd); } Class<?> paramType = paramTypes[argIndex]; try { resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam); } catch (TypeMismatchException ex) { throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), "Could not convert argument value of type [" + ObjectUtils.nullSafeClassName(argValue) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage()); } } return resolvedArgs; }
/** * Template method for resolving the specified argument which is supposed to be autowired. */ protected Object resolveAutowiredArgument( MethodParameter param, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) { if (InjectionPoint.class.isAssignableFrom(param.getParameterType())) { InjectionPoint injectionPoint = currentInjectionPoint.get(); if (injectionPoint == null) { throw new IllegalStateException("No current InjectionPoint available for " + param); } return injectionPoint; } return this.beanFactory.resolveDependency( new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter); }
static InjectionPoint setCurrentInjectionPoint(InjectionPoint injectionPoint) { InjectionPoint old = currentInjectionPoint.get(); if (injectionPoint != null) { currentInjectionPoint.set(injectionPoint); } else { currentInjectionPoint.remove(); } return old; }
@Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public Logger logger(InjectionPoint ip){ return LoggerFactory.getLogger(ip.getMember().getDeclaringClass()); }
@Bean @Scope("prototype") Logger logger(InjectionPoint ip) { return Logger.getLogger(ip.getMember().getDeclaringClass().getName()); }
private InjectionPoint findFailedInjectionPoint(BeanCreationException ex) { if (!(ex instanceof UnsatisfiedDependencyException)) { return null; } return ((UnsatisfiedDependencyException) ex).getInjectionPoint(); }
@Override protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<String>(1); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName)) { if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new RuntimeBeanReference(autowiredBeanName); } } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { ReflectionUtils.makeAccessible(field); field.set(bean, value); } }
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { Class<?> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(type, descriptor.getResolvableType().toString(), descriptor); } return null; } if (matchingBeans.size() > 1) { String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (primaryBeanName == null) { if (descriptor.isRequired() || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(type, matchingBeans); } else { // In case of an optional Collection/Map, silently ignore a non-unique case: // possibly it was meant to be an empty collection of multiple regular beans // (before 4.3 in particular when we didn't even look for collection beans). return null; } } if (autowiredBeanNames != null) { autowiredBeanNames.add(primaryBeanName); } return matchingBeans.get(primaryBeanName); } // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); if (autowiredBeanNames != null) { autowiredBeanNames.add(entry.getKey()); } return entry.getValue(); } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
/** * In order to avoid the boiler plate code of logger instantiation in each class we use the InjectionPoint * Functionality of stream. * * We use scope = prototype as a new Logger instance should be created for each Spring Bean * * @param injectionPoint * @return */ @Bean @Scope(value = "prototype") public Logger logger(InjectionPoint injectionPoint){ return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass()); }