Skip to content

Commit

Permalink
extracting VRaptorApplicationContext register methods to SpringRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
lucascs committed Jan 18, 2011
1 parent 13a7ebc commit b28d9ee
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 128 deletions.
Expand Up @@ -39,7 +39,7 @@ public class SpringBasedContainer extends AbstractComponentRegistry implements C
private final List<Class<?>> toRegister = new ArrayList<Class<?>>();

public SpringBasedContainer(ApplicationContext parentContext, BasicConfiguration config) {
applicationContext = new VRaptorApplicationContext(this, config);
applicationContext = new VRaptorApplicationContext(this, config, new SpringRegistry(this, config));
applicationContext.setParent(parentContext);
}

Expand All @@ -62,7 +62,7 @@ public <T> T instanceFor(Class<T> type) {
public <T> boolean canProvide(Class<T> type) {
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, type).length > 0;
}

public void start(ServletContext context) {
applicationContext.setServletContext(context);
applicationContext.refresh();
Expand Down
@@ -0,0 +1,145 @@
package br.com.caelum.vraptor.ioc.spring;

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.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopedProxyMode;

import br.com.caelum.vraptor.Converter;
import br.com.caelum.vraptor.config.BasicConfiguration;
import br.com.caelum.vraptor.core.BaseComponents;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.ioc.StereotypeHandler;

public class SpringRegistry {

private final AnnotationBeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private final SpringBasedContainer container;
private final BasicConfiguration config;

public SpringRegistry(SpringBasedContainer container, BasicConfiguration config) {
this.container = container;
this.config = config;
}

public void registerOn(BeanDefinitionRegistry registry, Class<?> type, boolean customComponent) {
AnnotatedGenericBeanDefinition definition = new AnnotatedGenericBeanDefinition(type);
definition.setLazyInit(true);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);
if (customComponent) {
definition.setPrimary(true);
definition.setRole(BeanDefinition.ROLE_APPLICATION);
} else {
definition.setPrimary(false);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
}

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

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

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}

/**
* From
* org.springframework.context.annotation.ClassPathBeanDefinitionScanner
* #applyScope()
*
* @param definition
* @param scopeMetadata
* @return
*/
private BeanDefinitionHolder applyScopeOn(BeanDefinitionRegistry registry, 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, registry, proxyTargetClass);
}
}

void registerOn(BeanDefinitionRegistry registry, Class<?> type) {
registerOn(registry, type, false);
}

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

void register(final Class<?> type, ConfigurableListableBeanFactory beanFactory) {
registerOn((BeanDefinitionRegistry) beanFactory, type, true);
registerFactory(type, beanFactory);
}

void registerPrototypeScopedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> prototypeComponent : BaseComponents.getPrototypeScoped().values()) {
registerOn(beanFactory, prototypeComponent);
}
}

void registerCachedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> cachedComponent : BaseComponents.getCachedComponents().values()) {
registerOn(beanFactory, cachedComponent, true);
}
}

void registerApplicationScopedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> type : BaseComponents.getApplicationScoped().values()) {
registerOn(beanFactory, type);
registerFactory(type, beanFactory);
}

for (Class<? extends StereotypeHandler> handlerType : BaseComponents.getStereotypeHandlers()) {
registerOn(beanFactory, handlerType);
}

registerOn(beanFactory, StereotypedBeansRegistrar.class);
registerOn(beanFactory, DefaultSpringLocator.class);

config.getServletContext();
}

void registerRequestScopedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> type : BaseComponents.getRequestScoped().values()) {
registerOn(beanFactory, type);
registerFactory(type, beanFactory);
}

for (Class<? extends Converter<?>> converterType : BaseComponents.getBundledConverters()) {
registerOn(beanFactory, converterType);
}

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

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

void registerVRaptorComponents(DefaultListableBeanFactory beanFactory) {
registerApplicationScopedComponentsOn(beanFactory);
registerRequestScopedComponentsOn(beanFactory);
registerPrototypeScopedComponentsOn(beanFactory);
}
}
Expand Up @@ -25,31 +25,20 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.config.AopConfigUtils;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
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.DefaultListableBeanFactory;
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.AbstractRefreshableWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import br.com.caelum.vraptor.Converter;
import br.com.caelum.vraptor.config.BasicConfiguration;
import br.com.caelum.vraptor.core.BaseComponents;
import br.com.caelum.vraptor.ioc.ComponentFactory;
import br.com.caelum.vraptor.ioc.StereotypeHandler;

import com.google.common.collect.MapMaker;

Expand All @@ -62,15 +51,17 @@ public class VRaptorApplicationContext extends AbstractRefreshableWebApplication

public static final String RESOURCES_LIST = "br.com.caelum.vraptor.resources.list";

private final AnnotationBeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
private final SpringBasedContainer container;
private final BasicConfiguration config;

private Map<Class<?>, String> typeToBeanName = new MapMaker().weakValues().makeMap();

public VRaptorApplicationContext(SpringBasedContainer container, BasicConfiguration config) {
private final SpringRegistry registry;

public VRaptorApplicationContext(SpringBasedContainer container, BasicConfiguration config, SpringRegistry registry) {
this.container = container;
this.config = config;
this.registry = registry;
}

@Override
Expand All @@ -85,9 +76,8 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
// beanFactory.ignoreDependencyType(ServletContext.class);
}

registerApplicationScopedComponentsOn(beanFactory);
registerRequestScopedComponentsOn(beanFactory);
registerPrototypeScopedComponentsOn(beanFactory);
registry.registerVRaptorComponents(beanFactory);

registerCustomComponentsOn(beanFactory);

if (config.isClasspathScanningEnabled()) {
Expand All @@ -100,7 +90,7 @@ protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(beanFactory);
registerCustomInjectionProcessor(beanFactory);
registerCachedComponentsOn(beanFactory);
registry.registerCachedComponentsOn(beanFactory);
}

private void scanPackages(DefaultListableBeanFactory beanFactory) {
Expand Down Expand Up @@ -129,119 +119,12 @@ private void scanWebInfClasses(DefaultListableBeanFactory beanFactory) {

private void registerCustomComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> type : container.getToRegister()) {
register(type, beanFactory);
}
}

private void registerPrototypeScopedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> prototypeComponent : BaseComponents.getPrototypeScoped().values()) {
registerOn(beanFactory, prototypeComponent);
}
}

private void registerCachedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> cachedComponent : BaseComponents.getCachedComponents().values()) {
registerOn(beanFactory, cachedComponent, true);
}
}

private void registerApplicationScopedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> type : BaseComponents.getApplicationScoped().values()) {
registerOn(beanFactory, type);
registerFactory(type, beanFactory);
}

for (Class<? extends StereotypeHandler> handlerType : BaseComponents.getStereotypeHandlers()) {
registerOn(beanFactory, handlerType);
}

registerOn(beanFactory, StereotypedBeansRegistrar.class);
registerOn(beanFactory, DefaultSpringLocator.class);

config.getServletContext();
}

private void registerRequestScopedComponentsOn(DefaultListableBeanFactory beanFactory) {
for (Class<?> type : BaseComponents.getRequestScoped().values()) {
registerOn(beanFactory, type);
registerFactory(type, beanFactory);
}

for (Class<? extends Converter<?>> converterType : BaseComponents.getBundledConverters()) {
registerOn(beanFactory, converterType);
}

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

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

private void register(final Class<?> type, ConfigurableListableBeanFactory beanFactory) {
registerOn((BeanDefinitionRegistry) beanFactory, type, true);
registerFactory(type, beanFactory);
}

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

public void register(Class<?> type) {
register(type, getBeanFactory());
}

private void registerOn(BeanDefinitionRegistry registry, Class<?> type) {
registerOn(registry, type, false);
}

private void registerOn(BeanDefinitionRegistry registry, Class<?> type, boolean customComponent) {
AnnotatedGenericBeanDefinition definition = new AnnotatedGenericBeanDefinition(type);
definition.setLazyInit(true);
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_NO);
if (customComponent) {
definition.setPrimary(true);
definition.setRole(BeanDefinition.ROLE_APPLICATION);
} else {
definition.setPrimary(false);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
}

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

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

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}

/**
* From
* org.springframework.context.annotation.ClassPathBeanDefinitionScanner
* #applyScope()
*
* @param definition
* @param scopeMetadata
* @return
*/
private BeanDefinitionHolder applyScopeOn(BeanDefinitionRegistry registry, 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, registry, proxyTargetClass);
}
registry.register(type, getBeanFactory());
}

private void registerCustomInjectionProcessor(BeanDefinitionRegistry registry) {
Expand All @@ -251,6 +134,7 @@ private void registerCustomInjectionProcessor(BeanDefinitionRegistry registry) {
registry.registerBeanDefinition(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, definition);
}

@Override
public <T> T getBean(Class<T> type) {
if (!typeToBeanName.containsKey(type)) {
logger.debug("Cache miss for {}", type);
Expand Down

0 comments on commit b28d9ee

Please sign in to comment.