* removed custom implementation of type lookup as {{{getBeanNamesForType}}} suddenly does work as expected
* added property to allow dedicated configuration, if {{{FactoryBean}}}s shall be initialized eagerly or not
git-svn-id: svn+ssh://svn.synyx.de/var/svn/synyx/opensource/synyx-plugin/trunk@2931 5a64d73e-33d6-4ccc-9058-23f8668ecac9
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
package org.synyx.plugin.core.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -8,11 +8,8 @@ import java.util.Map;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.config.ListFactoryBean;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
@@ -20,11 +17,30 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.synyx.plugin.core.PluginRegistry;
|
||||
|
||||
|
||||
/**
|
||||
* Simple {@link BeanFactoryPostProcessor} to autocreate lists of the configured
|
||||
* {@code lists} property. The post processor will register
|
||||
* {@link ListFactoryBean}s for each list named with the given key containing
|
||||
* all beans of the {@link org.springframework.context.ApplicationContext}
|
||||
* implementing the interface defines as lists value. E.g.:
|
||||
*
|
||||
* <pre>
|
||||
* <bean class="org.synyx.plugin.core.support.BeanListFactoryPostProcessor">
|
||||
* <property name="lists">
|
||||
* <map>
|
||||
* <entry key="beanName" value="org.synyx.plugin.core.Plugin" />
|
||||
* </map>
|
||||
* </property>
|
||||
* </bean>
|
||||
* </pre>
|
||||
*
|
||||
* This would register all Spring beans implementing the
|
||||
* {@link org.synyx.plugin.core.Plugin} interface in a list bean with the name
|
||||
* {@coder beanName}.
|
||||
*
|
||||
* @author Oliver Gierke - gierke@synyx.de
|
||||
*/
|
||||
public class BeanListBeanFactoryPostProcessor implements
|
||||
@@ -35,6 +51,8 @@ public class BeanListBeanFactoryPostProcessor implements
|
||||
|
||||
private Map<String, Class<?>> lists = new HashMap<String, Class<?>>();
|
||||
|
||||
private boolean initFactories = false;
|
||||
|
||||
|
||||
/**
|
||||
* Setter to inject required plugin registry configuration. The map's keys
|
||||
@@ -50,6 +68,23 @@ public class BeanListBeanFactoryPostProcessor implements
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setter to activate {@link org.springframework.beans.factory.FactoryBean}
|
||||
* scanning. This allows auto-registration of factory bean targets (the
|
||||
* objects actually created by the factory bean} but comes with the drawback
|
||||
* of having to initialize those factories eagerly. This can cause
|
||||
* unpredictable behaviour if other {@link BeanFactoryPostProcessor}s would
|
||||
* have been applied to these factories. Defaults to {@value #initFactories}
|
||||
* .
|
||||
*
|
||||
* @param initFactories the allowEagerInit to set
|
||||
*/
|
||||
public void setInitFactories(boolean initFactories) {
|
||||
|
||||
this.initFactories = initFactories;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
@@ -161,7 +196,10 @@ public class BeanListBeanFactoryPostProcessor implements
|
||||
protected List<RuntimeBeanReference> getBeanReferencesOfType(
|
||||
ConfigurableListableBeanFactory beanFactory, Class<?> type) {
|
||||
|
||||
List<String> beanNames = getBeanCandidates(beanFactory, type);
|
||||
// Lookup bean candidates either via Spring or manually
|
||||
List<String> beanNames =
|
||||
Arrays.asList(beanFactory.getBeanNamesForType(type, true,
|
||||
initFactories));
|
||||
|
||||
List<RuntimeBeanReference> beanReferences =
|
||||
new ManagedList(beanNames.size());
|
||||
@@ -176,62 +214,4 @@ public class BeanListBeanFactoryPostProcessor implements
|
||||
|
||||
return (List<RuntimeBeanReference>) beanReferences;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Looks up candidate beans for the given type from the {@link BeanFactory}.
|
||||
* Does <em>not</em> use Spring type lookup facilities as this initializes
|
||||
* {@link FactoryBean}s eagerly breaking possible registered
|
||||
* {@link BeanPostProcessor}s.
|
||||
* <p>
|
||||
* We traverse the entire {@link BeanFactory} hierarchy to lookup beans.
|
||||
*
|
||||
* @param beanFactory
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
private List<String> getBeanCandidates(
|
||||
ConfigurableListableBeanFactory beanFactory, Class<?> type) {
|
||||
|
||||
List<String> candidates = new ArrayList<String>();
|
||||
|
||||
// None given or most top bean factory reached?
|
||||
if (null == beanFactory) {
|
||||
return candidates;
|
||||
}
|
||||
|
||||
String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();
|
||||
|
||||
for (String beanName : beanDefinitionNames) {
|
||||
|
||||
BeanDefinition beanDefinition =
|
||||
beanFactory.getBeanDefinition(beanName);
|
||||
|
||||
// No bean class available at all
|
||||
if (!StringUtils.hasText(beanDefinition.getBeanClassName())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?> beanClass =
|
||||
Class.forName(beanDefinition.getBeanClassName());
|
||||
|
||||
if (type.isAssignableFrom(beanClass)) {
|
||||
candidates.add(beanName);
|
||||
}
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse parent bean factories
|
||||
if (beanFactory.getParentBeanFactory() instanceof ConfigurableListableBeanFactory) {
|
||||
candidates.addAll(getBeanCandidates(
|
||||
(ConfigurableListableBeanFactory) beanFactory
|
||||
.getParentBeanFactory(), type));
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user