0

假设我有一组实现一个接口和一个映射的 bean (a,b,c)。

xml

<bean name="map" class="java.util.HashMap"/>

abc.xml

<import M.xml>
<bean name="a" class="org.a"/>
<bean name="b" class="org.b"/>
<bean name="c" class="org.c"/>

定义.xml

<import M.xml>
<bean name="d" class="org.d"/>
<bean name="e" class="org.e"/>
<bean name="f" class="org.f"/>

一旦实例化配置,我希望将 a,b,c 放入地图中。当然a,b,c应该不知道地图。此注册应使用导入包含在配置中,因为在另一种情况下,它可能是必须注册的 d、e、f。我应该使用哪种 Spring 扩展机制?

谢谢

4

2 回答 2

1

我和你做过同样的事情。好的方法是使用BeanPostProcessorApplicationContextAware

首先,让 a、b、c 实现一个标记接口,例如:

public interface MappedValue { //leaving blank is ok because this is marker interface }

public a implements MappedValue { ... }
public b implements MappedValue { ... }
public c implements MappedValue { ... }

其次,定义并添加一个实现BeanPostProcessorApplicationContextAware的 bean到您的应用程序上下文中。

public class MapPopulator implements BeanPostProcessor, ApplicationContextAware{

    private ApplicationContext applicationContext;

    private String mapbeanName;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void setMapbeanName(String mapbeanName) {
        this.mapbeanName = mapbeanName;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        if( bean instanceof MappedValue){
            Map map = (Map)applicationContext.getBean( mapbeanName );
            map.put( beanName, bean );
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

希望它会有所帮助。

于 2013-03-13T12:03:18.687 回答
1

您可以使用@Autowired. 如果你用它标记一个集合,它会将所有匹配接口的bean放在这个集合中。您的“地图”bean 应该是MyMap以下类型:

public class MyMap implements Map {
  @Autowired
  private List<SharedInterface> foundBeans;

  @PostConstruct
  public void init() {
    // populate map by inserting objects from foundBeans with appropriate keys
  }
}

或者,使用原始“地图”bean并添加此类的mapBuilder bean:

public class MyMapBuilder {
  @Autowired
  private List<SharedInterface> foundBeans;

  @Resource(name="map")
  private Map map;

  @PostConstruct
  public void init() {
    // populate map by inserting objects from foundBeans with appropriate keys
  }
}
于 2013-03-13T11:15:05.963 回答