made SortedResourcesFactoryBean ResourceLoaderAware to prevent specifying the ResourceLoader in the jdbc NamespaceHandlers; prevents leaking of class loader instances in tooling

This commit is contained in:
Christian Dupuis 2010-03-17 17:35:27 +00:00
parent b8c0e153e3
commit e22431188b
4 changed files with 35 additions and 27 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -19,8 +19,6 @@ package org.springframework.jdbc.config;
import java.util.ArrayList;
import java.util.List;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@ -30,6 +28,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactoryBean;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
import org.w3c.dom.Element;
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses {@code embedded-database} element and
@ -72,7 +71,6 @@ public class EmbeddedDatabaseBeanDefinitionParser extends AbstractBeanDefinition
// Use a factory bean for the resources so they can be given an order if a pattern is used
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
.genericBeanDefinition(SortedResourcesFactoryBean.class);
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
resourcesFactory.addConstructorArgValue(locations);
builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -73,7 +73,6 @@ public class InitializeDatabaseBeanDefinitionParser extends AbstractBeanDefiniti
// Use a factory bean for the resources so they can be given an order if a pattern is used
BeanDefinitionBuilder resourcesFactory = BeanDefinitionBuilder
.genericBeanDefinition(SortedResourcesFactoryBean.class);
resourcesFactory.addConstructorArgValue(context.getReaderContext().getResourceLoader());
resourcesFactory.addConstructorArgValue(locations);
builder.addPropertyValue("scripts", resourcesFactory.getBeanDefinition());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,29 +24,51 @@ import java.util.Comparator;
import java.util.List;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
/**
* {@link FactoryBean} implementation that takes a list of location strings and creates a sorted array
* of {@link Resource} instances.
* @author Dave Syer
* @author Juergen Hoeller
* @author Christian Dupuis
* @since 3.0
*/
public class SortedResourcesFactoryBean implements FactoryBean<Resource[]> {
public class SortedResourcesFactoryBean extends AbstractFactoryBean<Resource[]> implements ResourceLoaderAware {
private final List<String> locations;
private final Resource[] resources;
private ResourceLoader resourceLoader;
public SortedResourcesFactoryBean(ResourceLoader resourceLoader, List<String> locations) throws IOException {
public SortedResourcesFactoryBean(List<String> locations) {
this.locations = locations;
setSingleton(true);
}
@Override
public Class<? extends Resource[]> getObjectType() {
return Resource[].class;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
protected Resource[] createInstance() throws Exception {
List<Resource> scripts = new ArrayList<Resource>();
for (String location : locations) {
if (resourceLoader instanceof ResourcePatternResolver) {
List<Resource> resources = new ArrayList<Resource>(
Arrays.asList(((ResourcePatternResolver) resourceLoader).getResources(location)));
List<Resource> resources = new ArrayList<Resource>(Arrays
.asList(((ResourcePatternResolver) resourceLoader).getResources(location)));
Collections.sort(resources, new Comparator<Resource>() {
public int compare(Resource o1, Resource o2) {
public int compare(Resource r1, Resource r2) {
try {
return o1.getURL().toString().compareTo(o2.getURL().toString());
return r1.getURL().toString().compareTo(r2.getURL().toString());
}
catch (IOException ex) {
return 0;
@ -61,19 +83,7 @@ public class SortedResourcesFactoryBean implements FactoryBean<Resource[]> {
scripts.add(resourceLoader.getResource(location));
}
}
this.resources = scripts.toArray(new Resource[scripts.size()]);
}
public Resource[] getObject() {
return this.resources;
}
public Class<? extends Resource[]> getObjectType() {
return Resource[].class;
}
public boolean isSingleton() {
return true;
return scripts.toArray(new Resource[scripts.size()]);
}
}

View File

@ -23,6 +23,7 @@ Import-Template:
org.apache.commons.logging.*;version="[1.1.1, 2.0.0)",
org.springframework.beans.*;version=${spring.osgi.range},
org.springframework.core.*;version=${spring.osgi.range},
org.springframework.context.*;version=${spring.osgi.range},
org.springframework.dao.*;version=${spring.osgi.range},
org.springframework.jndi.*;version=${spring.osgi.range};resolution:=optional,
org.springframework.transaction.*;version=${spring.osgi.range},