Java Code Examples for org.springframework.beans.factory.config.ConfigurableBeanFactory#setCurrentlyInCreation()

The following examples show how to use org.springframework.beans.factory.config.ConfigurableBeanFactory#setCurrentlyInCreation() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ConfigurationClassEnhancer.java    From spring-analysis-note with MIT License 4 votes vote down vote up
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
		ConfigurableBeanFactory beanFactory, String beanName) {

	// The user (i.e. not the factory) is requesting this bean through a call to
	// the bean method, direct or indirect. The bean may have already been marked
	// as 'in creation' in certain autowiring scenarios; if so, temporarily set
	// the in-creation status to false in order to avoid an exception.
	boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
	try {
		if (alreadyInCreation) {
			beanFactory.setCurrentlyInCreation(beanName, false);
		}
		boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
		if (useArgs && beanFactory.isSingleton(beanName)) {
			// Stubbed null arguments just for reference purposes,
			// expecting them to be autowired for regular singleton references?
			// A safe assumption since @Bean singleton arguments cannot be optional...
			for (Object arg : beanMethodArgs) {
				if (arg == null) {
					useArgs = false;
					break;
				}
			}
		}
		Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
				beanFactory.getBean(beanName));
		if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
			// Detect package-protected NullBean instance through equals(null) check
			if (beanInstance.equals(null)) {
				if (logger.isDebugEnabled()) {
					logger.debug(String.format("@Bean method %s.%s called as bean reference " +
							"for type [%s] returned null bean; resolving to null value.",
							beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
							beanMethod.getReturnType().getName()));
				}
				beanInstance = null;
			}
			else {
				String msg = String.format("@Bean method %s.%s called as bean reference " +
						"for type [%s] but overridden by non-compatible bean instance of type [%s].",
						beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
						beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
				try {
					BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
					msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Ignore - simply no detailed message then.
				}
				throw new IllegalStateException(msg);
			}
		}
		Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
		if (currentlyInvoked != null) {
			String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
			beanFactory.registerDependentBean(beanName, outerBeanName);
		}
		return beanInstance;
	}
	finally {
		if (alreadyInCreation) {
			beanFactory.setCurrentlyInCreation(beanName, true);
		}
	}
}
 
Example 2
Source File: ConfigurationClassEnhancer.java    From java-technology-stack with MIT License 4 votes vote down vote up
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
		ConfigurableBeanFactory beanFactory, String beanName) {

	// The user (i.e. not the factory) is requesting this bean through a call to
	// the bean method, direct or indirect. The bean may have already been marked
	// as 'in creation' in certain autowiring scenarios; if so, temporarily set
	// the in-creation status to false in order to avoid an exception.
	boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
	try {
		if (alreadyInCreation) {
			beanFactory.setCurrentlyInCreation(beanName, false);
		}
		boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
		if (useArgs && beanFactory.isSingleton(beanName)) {
			// Stubbed null arguments just for reference purposes,
			// expecting them to be autowired for regular singleton references?
			// A safe assumption since @Bean singleton arguments cannot be optional...
			for (Object arg : beanMethodArgs) {
				if (arg == null) {
					useArgs = false;
					break;
				}
			}
		}
		Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
				beanFactory.getBean(beanName));
		if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
			// Detect package-protected NullBean instance through equals(null) check
			if (beanInstance.equals(null)) {
				if (logger.isDebugEnabled()) {
					logger.debug(String.format("@Bean method %s.%s called as bean reference " +
							"for type [%s] returned null bean; resolving to null value.",
							beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
							beanMethod.getReturnType().getName()));
				}
				beanInstance = null;
			}
			else {
				String msg = String.format("@Bean method %s.%s called as bean reference " +
						"for type [%s] but overridden by non-compatible bean instance of type [%s].",
						beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
						beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
				try {
					BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
					msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Ignore - simply no detailed message then.
				}
				throw new IllegalStateException(msg);
			}
		}
		Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
		if (currentlyInvoked != null) {
			String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
			beanFactory.registerDependentBean(beanName, outerBeanName);
		}
		return beanInstance;
	}
	finally {
		if (alreadyInCreation) {
			beanFactory.setCurrentlyInCreation(beanName, true);
		}
	}
}
 
Example 3
Source File: ConfigurationClassEnhancer.java    From lams with GNU General Public License v2.0 4 votes vote down vote up
private Object obtainBeanInstanceFromFactory(Method beanMethod, Object[] beanMethodArgs,
		ConfigurableBeanFactory beanFactory, String beanName) {

	// The user (i.e. not the factory) is requesting this bean through a call to
	// the bean method, direct or indirect. The bean may have already been marked
	// as 'in creation' in certain autowiring scenarios; if so, temporarily set
	// the in-creation status to false in order to avoid an exception.
	boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
	try {
		if (alreadyInCreation) {
			beanFactory.setCurrentlyInCreation(beanName, false);
		}
		boolean useArgs = !ObjectUtils.isEmpty(beanMethodArgs);
		if (useArgs && beanFactory.isSingleton(beanName)) {
			// Stubbed null arguments just for reference purposes,
			// expecting them to be autowired for regular singleton references?
			// A safe assumption since @Bean singleton arguments cannot be optional...
			for (Object arg : beanMethodArgs) {
				if (arg == null) {
					useArgs = false;
					break;
				}
			}
		}
		Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
				beanFactory.getBean(beanName));
		if (beanInstance != null && !ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
			String msg = String.format("@Bean method %s.%s called as a bean reference " +
						"for type [%s] but overridden by non-compatible bean instance of type [%s].",
						beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
						beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
			try {
				BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
				msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore - simply no detailed message then.
			}
			throw new IllegalStateException(msg);
		}
		Method currentlyInvoked = SimpleInstantiationStrategy.getCurrentlyInvokedFactoryMethod();
		if (currentlyInvoked != null) {
			String outerBeanName = BeanAnnotationHelper.determineBeanNameFor(currentlyInvoked);
			beanFactory.registerDependentBean(beanName, outerBeanName);
		}
		return beanInstance;
	}
	finally {
		if (alreadyInCreation) {
			beanFactory.setCurrentlyInCreation(beanName, true);
		}
	}
}
 
Example 4
Source File: ConfigurationClassEnhancer.java    From spring4-understanding with Apache License 2.0 4 votes vote down vote up
/**
 * Enhance a {@link Bean @Bean} method to check the supplied BeanFactory for the
 * existence of this bean object.
 * @throws Throwable as a catch-all for any exception that may be thrown when invoking the
 * super implementation of the proxied method i.e., the actual {@code @Bean} method
 */
@Override
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
			MethodProxy cglibMethodProxy) throws Throwable {

	ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
	String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);

	// Determine whether this bean is a scoped-proxy
	Scope scope = AnnotationUtils.findAnnotation(beanMethod, Scope.class);
	if (scope != null && scope.proxyMode() != ScopedProxyMode.NO) {
		String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
		if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
			beanName = scopedBeanName;
		}
	}

	// To handle the case of an inter-bean method reference, we must explicitly check the
	// container for already cached instances.

	// First, check to see if the requested bean is a FactoryBean. If so, create a subclass
	// proxy that intercepts calls to getObject() and returns any cached bean instance.
	// This ensures that the semantics of calling a FactoryBean from within @Bean methods
	// is the same as that of referring to a FactoryBean within XML. See SPR-6602.
	if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
			factoryContainsBean(beanFactory, beanName)) {
		Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
		if (factoryBean instanceof ScopedProxyFactoryBean) {
			// Pass through - scoped proxy factory beans are a special case and should not
			// be further proxied
		}
		else {
			// It is a candidate FactoryBean - go ahead with enhancement
			return enhanceFactoryBean(factoryBean, beanFactory, beanName);
		}
	}

	if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
		// The factory is calling the bean method in order to instantiate and register the bean
		// (i.e. via a getBean() call) -> invoke the super implementation of the method to actually
		// create the bean instance.
		if (BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) {
			logger.warn(String.format("@Bean method %s.%s is non-static and returns an object " +
					"assignable to Spring's BeanFactoryPostProcessor interface. This will " +
					"result in a failure to process annotations such as @Autowired, " +
					"@Resource and @PostConstruct within the method's declaring " +
					"@Configuration class. Add the 'static' modifier to this method to avoid " +
					"these container lifecycle issues; see @Bean javadoc for complete details.",
					beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName()));
		}
		return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
	}
	else {
		// The user (i.e. not the factory) is requesting this bean through a
		// call to the bean method, direct or indirect. The bean may have already been
		// marked as 'in creation' in certain autowiring scenarios; if so, temporarily
		// set the in-creation status to false in order to avoid an exception.
		boolean alreadyInCreation = beanFactory.isCurrentlyInCreation(beanName);
		try {
			if (alreadyInCreation) {
				beanFactory.setCurrentlyInCreation(beanName, false);
			}
			Object beanInstance = (!ObjectUtils.isEmpty(beanMethodArgs) ?
					beanFactory.getBean(beanName, beanMethodArgs) : beanFactory.getBean(beanName));
			if (beanInstance != null && !ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
				String msg = String.format("@Bean method %s.%s called as a bean reference " +
							"for type [%s] but overridden by non-compatible bean instance of type [%s].",
							beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
							beanMethod.getReturnType().getName(), beanInstance.getClass().getName());
				try {
					BeanDefinition beanDefinition = beanFactory.getMergedBeanDefinition(beanName);
					msg += " Overriding bean of same name declared in: " + beanDefinition.getResourceDescription();
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Ignore - simply no detailed message then.
				}
				throw new IllegalStateException(msg);
			}
			return beanInstance;
		}
		finally {
			if (alreadyInCreation) {
				beanFactory.setCurrentlyInCreation(beanName, true);
			}
		}
	}
}