Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make sure the application and pluginManager are only created once, an…
…d combine scanning and non scanning configuration classes into one to simplify things
- Loading branch information
1 parent
fc681b1
commit ec766ca
Showing
5 changed files
with
81 additions
and
111 deletions.
There are no files selected for viewing
92 changes: 65 additions & 27 deletions
92
grails-web-boot/src/main/groovy/grails/boot/config/GrailsConfiguration.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,90 @@ | ||
package grails.boot.config | ||
|
||
import groovy.transform.CompileStatic | ||
import org.codehaus.groovy.grails.commons.DefaultGrailsApplication | ||
import org.codehaus.groovy.grails.commons.GrailsApplication | ||
import org.codehaus.groovy.grails.plugins.DefaultGrailsPluginManager | ||
import org.codehaus.groovy.grails.plugins.GrailsPluginManager | ||
import org.grails.boot.support.GrailsPluginManagerPostProcessor | ||
import org.grails.boot.support.GrailsApplicationPostProcessor | ||
import org.springframework.context.ResourceLoaderAware | ||
import org.springframework.context.annotation.Bean | ||
import org.springframework.core.io.Resource | ||
import org.springframework.core.io.ResourceLoader | ||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver | ||
import org.springframework.core.io.support.ResourcePatternResolver | ||
import org.springframework.core.type.classreading.CachingMetadataReaderFactory | ||
import org.springframework.util.ClassUtils | ||
|
||
/** | ||
* A handy utility class for creating a Grails Boot configuration | ||
* A Grails configuration that scans for classes using the packages defined by the packages() method and creates the necessary | ||
* {@link org.codehaus.groovy.grails.commons.GrailsApplication} and {@link org.codehaus.groovy.grails.plugins.GrailsPluginManager} beans | ||
* that constitute a Grails application. | ||
* | ||
* @see GrailsApplicationPostProcessor | ||
* | ||
* @author Graeme Rocher | ||
* @since 3.0 | ||
*/ | ||
@CompileStatic | ||
abstract class GrailsConfiguration { | ||
class GrailsConfiguration implements ResourceLoaderAware { | ||
|
||
/** | ||
* @return The classes that constitute the Grails application | ||
*/ | ||
abstract Collection<Class> classes() | ||
public static final String CLASS_RESOURCE_PATTERN = "/**/*.class" | ||
|
||
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver() | ||
|
||
/** | ||
* @return The {@link GrailsApplication} instance | ||
* @return A post processor that uses the {@link org.codehaus.groovy.grails.plugins.GrailsPluginManager} to configure the {@link org.springframework.context.ApplicationContext} | ||
*/ | ||
@Bean(destroyMethod = 'clear') | ||
GrailsApplication grailsApplication() { | ||
def application = new DefaultGrailsApplication( classes() as Class[] ) | ||
application.initialise() | ||
return application | ||
@Bean | ||
GrailsApplicationPostProcessor grailsApplicationPostProcessor() { | ||
return new GrailsApplicationPostProcessor(classes() as Class[]) | ||
} | ||
|
||
/** | ||
* @return The {@link GrailsPluginManager} instance | ||
* @return The classes that constitute the Grails application | ||
*/ | ||
@Bean(destroyMethod = 'shutdown') | ||
GrailsPluginManager pluginManager() { | ||
def manager = new DefaultGrailsPluginManager(grailsApplication()) | ||
manager.loadPlugins() | ||
return manager | ||
Collection<Class> classes() { | ||
def readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver) | ||
def packages = packages() | ||
Collection<Class> classes = [] | ||
for (pkg in packages) { | ||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + | ||
ClassUtils.convertClassNameToResourcePath(pkg.name) + CLASS_RESOURCE_PATTERN; | ||
|
||
classes.addAll scanUsingPattern(pattern, readerFactory) | ||
} | ||
|
||
// try the default package in case of a script without recursing into subpackages | ||
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + "*.class" | ||
classes.addAll scanUsingPattern(pattern, readerFactory) | ||
|
||
|
||
return classes | ||
} | ||
|
||
/** | ||
* @return A post processor that uses the {@link GrailsPluginManager} to configure the {@link org.springframework.context.ApplicationContext} | ||
* @return The packages to scan | ||
*/ | ||
@Bean | ||
GrailsPluginManagerPostProcessor pluginManagerPostProcessor() { | ||
return new GrailsPluginManagerPostProcessor(pluginManager()) | ||
Collection<Package> packages() { | ||
[ getClass().package ] | ||
} | ||
|
||
@Override | ||
void setResourceLoader(ResourceLoader resourceLoader) { | ||
this.resourcePatternResolver = new PathMatchingResourcePatternResolver(resourceLoader) | ||
} | ||
|
||
private Collection<Class> scanUsingPattern(String pattern, CachingMetadataReaderFactory readerFactory) { | ||
def resources = this.resourcePatternResolver.getResources(pattern) | ||
def classLoader = Thread.currentThread().contextClassLoader | ||
Collection<Class> classes = [] | ||
for (Resource res in resources) { | ||
// ignore closures / inner classes | ||
if(!res.filename.contains('$')) { | ||
def reader = readerFactory.getMetadataReader(res) | ||
def metadata = reader.annotationMetadata | ||
if (metadata.annotationTypes.any() { String annotation -> annotation.startsWith('grails.') }) { | ||
classes << classLoader.loadClass(reader.classMetadata.className) | ||
} | ||
} | ||
} | ||
return classes | ||
} | ||
|
||
} |
74 changes: 0 additions & 74 deletions
74
grails-web-boot/src/main/groovy/grails/boot/config/ScanningGrailsConfiguration.groovy
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters