I added automatic component scanning to the Spring module. Just
wanted to run it by you--if pepite likes it he can add into the
official module. I've attached the patches at the end of this email.
Please feel free to comment. You can look at my fork of the module on
github at: http://github.com/dcardon/Play--framework-Spring-module
Thanks!
--Dave
From 9a627a698fce5d52bf65f984d3d29a21ef71b5db Mon Sep 17 00:00:00 2001
From: David Cardon <dca...@enticelabs.com>
Date: Thu, 4 Mar 2010 09:44:25 -0700
Subject: [PATCH 1/2] -Added component scanning to plugin
---
src/play/modules/spring/SpringPlugin.java | 26 +++++++++++++++++++++
+++--
1 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/src/play/modules/spring/SpringPlugin.java b/src/play/
modules/spring/SpringPlugin.java
index 54bc48e..a7b0578 100644
--- a/src/play/modules/spring/SpringPlugin.java
+++ b/src/play/modules/spring/SpringPlugin.java
@@ -7,6 +7,7 @@ import java.util.Map;
import org.springframework.beans.factory.BeanCreationException;
import
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import
org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.GenericApplicationContext;
import org.xml.sax.InputSource;
import play.Logger;
@@ -20,8 +21,15 @@ import play.inject.Injector;
import play.vfs.VirtualFile;
public class SpringPlugin extends PlayPlugin implements BeanSource {
-
- public static GenericApplicationContext applicationContext;
+ /**
+ * Component scanning constants.
+ */
+ private static final String PLAY_SPRING_COMPONENT_SCAN_FLAG =
"play.spring.component-scan";
+ private static final String
PLAY_SPRING_COMPONENT_SCAN_BASE_PACKAGES = "play.spring.component-
scan.base-packages";
+ private static final String TRUE_STR = "true";
+ private static final String FALSE_STR = "false";
+
+ public static GenericApplicationContext applicationContext;
private long startDate = 0;
@Override
@@ -65,6 +73,20 @@ public class SpringPlugin extends PlayPlugin
implements BeanSource {
PropertyPlaceholderConfigurer configurer = new
PropertyPlaceholderConfigurer();
configurer.setProperties(Play.configuration);
applicationContext.addBeanFactoryPostProcessor(configurer);
+ //
+ // Check for component scan
+ //
+ boolean doComponentScan =
Play.configuration.getProperty(PLAY_SPRING_COMPONENT_SCAN_FLAG,FALSE_STR).equals(TRUE_STR);
+ Logger.debug("Spring configuration do component scan:
" + doComponentScan);
+ if (doComponentScan)
+ {
+ ClassPathBeanDefinitionScanner scanner = new
PlayClassPathBeanDefinitionScanner(applicationContext);
+ String scanBasePackage =
Play.configuration.getProperty(PLAY_SPRING_COMPONENT_SCAN_BASE_PACKAGES,"");
+ Logger.debug("Base package for scan: " +
scanBasePackage);
+ Logger.debug("Scanning...");
+ scanner.scan(scanBasePackage.split(","));
+ Logger.debug("... component scanning complete");
+ }
is = url.openStream();
xmlReader.loadBeanDefinitions(new InputSource(is));
--
1.6.4.msysgit.0
From 4fb11cead7f14fb80f4e8134b94c73358b24a8d0 Mon Sep 17 00:00:00 2001
From: David Cardon <dca...@enticelabs.com>
Date: Thu, 4 Mar 2010 09:45:42 -0700
Subject: [PATCH 2/2] -Added custom play classpath scanner.
---
.../spring/PlayClassPathBeanDefinitionScanner.java | 85 ++++++++++++
++++++++
1 files changed, 85 insertions(+), 0 deletions(-)
create mode 100644 src/play/modules/spring/
PlayClassPathBeanDefinitionScanner.java
diff --git a/src/play/modules/spring/
PlayClassPathBeanDefinitionScanner.java b/src/play/modules/spring/
PlayClassPathBeanDefinitionScanner.java
new file mode 100644
index 0000000..a5aa8d7
--- /dev/null
+++ b/src/play/modules/spring/PlayClassPathBeanDefinitionScanner.java
@@ -0,0 +1,85 @@
+package play.modules.spring;
+
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import
org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import
org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import
org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import
org.springframework.context.annotation.ScannedGenericBeanDefinition;
+import org.springframework.core.io.ByteArrayResource;
+import
org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import
org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.core.type.classreading.MetadataReader;
+import
org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.stereotype.Component;
+
+import play.Logger;
+import play.Play;
+import play.classloading.ApplicationClasses.ApplicationClass;
+
+public class PlayClassPathBeanDefinitionScanner extends
ClassPathBeanDefinitionScanner
+{
+ private ResourcePatternResolver resourcePatternResolver = new
PathMatchingResourcePatternResolver();
+
+ private MetadataReaderFactory metadataReaderFactory = new
CachingMetadataReaderFactory(
+ this .resourcePatternResolver);
+
+ /**
+ * The constructor, which just passed on to the parent class.
+ *
+ * @param registry
+ */
+ public PlayClassPathBeanDefinitionScanner(BeanDefinitionRegistry
registry)
+ {
+ super(registry);
+ }
+
+ /**
+ * The override, which searches through the play framework's
classes, instead of using
+ * files (as Spring is trained to do).
+ */
+ @Override
+ public Set<BeanDefinition> findCandidateComponents(String
basePackage)
+ {
+ Logger.debug("Finding candidate components with base package: " +
basePackage);
+
+ Set<BeanDefinition> candidates = new
LinkedHashSet<BeanDefinition>();
+
+ try
+ {
+ for (ApplicationClass appClass : Play.classes.all())
+ {
+ if (appClass.name.startsWith(basePackage))
+ {
+ Logger.debug("Scanning class: " + appClass.name);
+ ByteArrayResource res = new
ByteArrayResource(appClass.enhance());
+ MetadataReader metadataReader =
this.metadataReaderFactory.getMetadataReader(res);
+
+ if (isCandidateComponent(metadataReader))
+ {
+ ScannedGenericBeanDefinition sbd = new
ScannedGenericBeanDefinition(metadataReader);
+ sbd.setSource(res);
+ if (isCandidateComponent(sbd))
+ {
+ candidates.add(sbd);
+ }
+ }
+ }
+ else
+ {
+ Logger.trace("Skipped class: " + appClass.name + " -- wrong base
package");
+ }
+ }
+ }
+ catch (IOException ex)
+ {
+ throw new BeanDefinitionStoreException(
+ "I/O failure during classpath scanning", ex);
+ }
+ return candidates;
+ }
+}
--
1.6.4.msysgit.0
--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To post to this group, send email to play-fr...@googlegroups.com.
To unsubscribe from this group, send email to play-framewor...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/play-framework?hl=en.
Thanks for your contribution :) I will have a look at it as soon as possible,
Nicolas
I've not tested it with Spring 3.0, but I know that it supports
@Component, @Service, etc... for Spring 2.5. I looked into this a
little bit and it appears the Spring class I extend to do the scanning
has not changed since version 2.5---I would expect it to work
correctly with 3.0, but the best answer is to try it out. :)
I'm pretty sure that Play!'s datasource is not automatically
registered in Spring, so you'd probably have to do that yourself.
--Dave
On Mar 4, 6:42 pm, 曹江华 <tujiao....@gmail.com> wrote:
> as well as can support share the play!'s datasource?
>
>
>
> On Fri, Mar 5, 2010 at 9:41 AM, 曹江华 <tujiao....@gmail.com> wrote:
> > can support the Spring 3.0's annotation?
>
> > On Fri, Mar 5, 2010 at 3:26 AM, The Dave <the.dave.car...@gmail.com>wrote:
>
> >> Hi all!
>
> >> I added automatic component scanning to the Spring module. Just
> >> wanted to run it by you--if pepite likes it he can add into the
> >> official module. I've attached the patches at the end of this email.
>
> >> Please feel free to comment. You can look at my fork of the module on
> >> github at:http://github.com/dcardon/Play--framework-Spring-module
>
> >> Thanks!
>
> >> --Dave
>
> >> From 9a627a698fce5d52bf65f984d3d29a21ef71b5db Mon Sep 17 00:00:00 2001
> >> From: David Cardon <dcar...@enticelabs.com>
> >> From: David Cardon <dcar...@enticelabs.com>
> >> play-framewor...@googlegroups.com<play-framework%2Bunsu...@googlegroups.com>
I have just pushed your changes and release the module. Thanks again.
Nicolas
On 4 mrt 2010, at 20:26, The Dave wrote:
> --
> You received this message because you are subscribed to the Google Groups "play-framework" group.
> To post to this group, send email to play-fr...@googlegroups.com.
> To unsubscribe from this group, send email to play-framewor...@googlegroups.com.