diff --git a/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringBasedContainer.java b/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringBasedContainer.java index ff7e2287d..0011b4707 100644 --- a/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringBasedContainer.java +++ b/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringBasedContainer.java @@ -39,7 +39,7 @@ public class SpringBasedContainer extends AbstractComponentRegistry implements C private final List> toRegister = new ArrayList>(); public SpringBasedContainer(ApplicationContext parentContext, BasicConfiguration config) { - applicationContext = new VRaptorApplicationContext(this, config); + applicationContext = new VRaptorApplicationContext(this, config, new SpringRegistry(this, config)); applicationContext.setParent(parentContext); } @@ -62,7 +62,7 @@ public T instanceFor(Class type) { public boolean canProvide(Class type) { return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(applicationContext, type).length > 0; } - + public void start(ServletContext context) { applicationContext.setServletContext(context); applicationContext.refresh(); diff --git a/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringRegistry.java b/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringRegistry.java new file mode 100644 index 000000000..dcebb9f43 --- /dev/null +++ b/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/SpringRegistry.java @@ -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 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> 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); + } +} diff --git a/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/VRaptorApplicationContext.java b/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/VRaptorApplicationContext.java index 24cc36067..ccc2e2fa2 100644 --- a/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/VRaptorApplicationContext.java +++ b/vraptor-core/src/main/java/br/com/caelum/vraptor/ioc/spring/VRaptorApplicationContext.java @@ -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; @@ -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, 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 @@ -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()) { @@ -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) { @@ -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 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> 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) { @@ -251,6 +134,7 @@ private void registerCustomInjectionProcessor(BeanDefinitionRegistry registry) { registry.registerBeanDefinition(AnnotationConfigUtils.AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME, definition); } + @Override public T getBean(Class type) { if (!typeToBeanName.containsKey(type)) { logger.debug("Cache miss for {}", type);