All Downloads are FREE. Search and download functionalities are using the official Maven repository.

br.com.caelum.vraptor.ioc.spring.SpringRegistry Maven / Gradle / Ivy

There is a newer version: 4.3.0-beta-3
Show newest version
/***
 * Copyright (c) 2009 Caelum - www.caelum.com.br/opensource All rights reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package br.com.caelum.vraptor.ioc.spring;

import java.util.Arrays;
import java.util.Collection;

import org.springframework.aop.config.AopConfigUtils;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.core.Ordered;
import org.springframework.web.context.support.WebApplicationContextUtils;

import br.com.caelum.vraptor.core.BaseComponents;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.ioc.Container;

/**
 * Class responsible for registering beans on spring.
 * 
 * @author Lucas Cavalcanti
 * @author Douglas Campos (qmx)
 * @since 3.3.0
 */
public class SpringRegistry {

	private final BeanNameGenerator beanNameGenerator = new UniqueBeanNameGenerator(new AnnotationBeanNameGenerator());
	private final ConfigurableListableBeanFactory beanFactory;
	private final VRaptorScopeResolver scopeResolver = new VRaptorScopeResolver();
	private final Container container;

	public SpringRegistry(ConfigurableListableBeanFactory configurableListableBeanFactory, Container container) {
		this.beanFactory = configurableListableBeanFactory;
		this.container = container;
	}

	private void registerOn(Class type, boolean customComponent) {
		AnnotatedGenericBeanDefinition definition = new AnnotatedGenericBeanDefinition(type);
		if (!customComponent) {
			definition.setLazyInit(true);
		}
		definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);
		definition.setPrimary(customComponent);
		definition.setRole(customComponent ? BeanDefinition.ROLE_APPLICATION : BeanDefinition.ROLE_INFRASTRUCTURE);

		String name = beanNameGenerator.generateBeanName(definition, (BeanDefinitionRegistry) beanFactory);
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(definition, name);

		ScopeMetadata scopeMetadata = scopeResolver.resolveScopeMetadata(definition);
		definitionHolder = applyScopeOn(definitionHolder, scopeMetadata);

		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, (BeanDefinitionRegistry) beanFactory);
	}

	/**
	 * From org.springframework.context.annotation.ClassPathBeanDefinitionScanner#applyScope()
	 * @param definition
	 * @param scopeMetadata
	 *
	 * @return
	 */
	private BeanDefinitionHolder applyScopeOn(BeanDefinitionHolder definition, ScopeMetadata scopeMetadata) {
		String scope = scopeMetadata.getScopeName();
		ScopedProxyMode proxyMode = scopeMetadata.getScopedProxyMode();
		definition.getBeanDefinition().setScope(scope);
		if (BeanDefinition.SCOPE_SINGLETON.equals(scope) || BeanDefinition.SCOPE_PROTOTYPE.equals(scope)
				|| proxyMode.equals(ScopedProxyMode.NO)) {
			return definition;
		} else {
			boolean proxyTargetClass = proxyMode.equals(ScopedProxyMode.TARGET_CLASS);
			return ScopedProxyUtils.createScopedProxy(definition, (BeanDefinitionRegistry) beanFactory, proxyTargetClass);
		}
	}

	private void registerOn(Class type) {
		registerOn(type, false);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void registerFactory(final Class type) {
		if (ComponentFactory.class.isAssignableFrom(type)) {
			beanFactory.registerSingleton(type.getName(), new ComponentFactoryBean(container, type));
		}
	}

	void register(final Class type) {
		register(type, true);
	}

	private void register(final Class type, boolean customComponent) {
		registerOn(type, customComponent);
		registerFactory(type);
	}

	private void registerPrototypeScopedComponentsOn() {
		for (Class prototypeComponent : BaseComponents.getPrototypeScoped().values()) {
			registerOn(prototypeComponent);
		}
	}

	private void registerCachedComponentsOn() {
		for (Class cachedComponent : BaseComponents.getCachedComponents().values()) {
			registerOn(cachedComponent, true);
		}
	}

	private void registerApplicationScopedComponentsOn() {
		registerComponents(BaseComponents.getApplicationScoped().values());

		registerComponents(Arrays.asList(BaseComponents.getStereotypeHandlers()));

		registerOn(StereotypedBeansRegistrar.class);
		registerOn(DefaultSpringLocator.class);
	}

	private void registerRequestScopedComponentsOn() {
		registerComponents(BaseComponents.getRequestScoped().values());

		registerComponents(BaseComponents.getBundledConverters());

		registerOn(VRaptorRequestProvider.class, true);
		registerOn(HttpServletRequestProvider.class, true);
		registerOn(HttpServletResponseProvider.class, true);
		registerOn(HttpSessionProvider.class, true);

		beanFactory.registerSingleton(SpringBasedContainer.class.getName(), container);
	}

	private void registerVRaptorComponents() {
		registerApplicationScopedComponentsOn();
		registerRequestScopedComponentsOn();
		registerPrototypeScopedComponentsOn();
	}

	private void registerCustomInjectionProcessor() {
		RootBeanDefinition definition = new RootBeanDefinition(InjectionBeanPostProcessor.class);
		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		definition.getPropertyValues().addPropertyValue("order", Ordered.LOWEST_PRECEDENCE);
		((BeanDefinitionRegistry) beanFactory).registerBeanDefinition(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, definition);
	}

	void registerCustomComponents(Collection> toRegister) {
		for (Class type : toRegister) {
			register(type);
		}
	}

	private  void registerComponents(Collection> toRegister) {
		for (Class type : toRegister) {
			register(type, false);
		}
	}

	void configure() {
		registerVRaptorComponents();

		AnnotationConfigUtils.registerAnnotationConfigProcessors((BeanDefinitionRegistry) beanFactory);
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary((BeanDefinitionRegistry) beanFactory);

		registerCustomInjectionProcessor();

		registerCachedComponentsOn();

		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy