spring beanpostprocessor不适用于组件扫描?

时间:2009-07-13 19:30:28

标签: java spring

我有许多cookie-cutter spring bean,并且不想在xml中明确定义每个bean。所以我去了组件扫描路线,让我这样做。这很好,但我刚刚意识到没有为使用组件扫描技术加载的bean调用MyBeanPostProcessor。 MyBeanPostProcessor只是尝试对这些bean进行一些setter注入。以下配置只显示我尝试过的这种方法无法正常工作。关于如何在这些bean上进行setter注入的任何其他想法?

我正在使用 Spring 2.5.5

谢谢, 本

<context:component-scan base-package="us.benanderson" 
        use-default-filters="false" 
        annotation-config="false"
        scope-resolver="us.benanderson.MyScopeResolver"
        name-generator="us.benanderson.MyBeanNameGenerator">
    <context:include-filter type="custom" expression="us.benanderson.MyTypeFilter" />
</context:component-scan>
<bean class="us.benanderson.MyBeanPostProcessor">
    <property name="order" value="500" />
</bean>

2 个答案:

答案 0 :(得分:5)

这是我的测试用例,似乎有效(Spring 2.5.6)。为了简洁,我考虑排除一些文件,但我决定反对它。

Start.java(入口点)

package se.waxwing.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Start {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("se/waxwing/test/Context.xml");
        context.getBean("customBean");
    }
}

context.xml中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">


    <context:component-scan base-package="se.waxwing.test" 
        use-default-filters="false" 
        annotation-config="false"
        scope-resolver="se.waxwing.test.MyScopeResolver">
        <context:include-filter type="custom" expression="se.waxwing.test.MyTypeFilter" />
    </context:component-scan>

    <bean id="beanProcessor" class="se.waxwing.test.MyBeanPostProcessor" />

</beans>

CustomBean.java(这是我想要查找的 - 请参阅MyTypeFilter)

package se.waxwing.test;

public class CustomBean {

    public CustomBean() {
        System.err.println("instantiating component");
    }
}

MyBeanPostProcessor.java

package se.waxwing.test;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class MyBeanPostProcessor implements BeanPostProcessor {

    public MyBeanPostProcessor() {
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.err.println("after " + beanName);
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.err.println("before " + beanName);
        return bean;
    }   
}

MyScopeResolver.java

package se.waxwing.test;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;
import org.springframework.context.annotation.ScopedProxyMode;

public class MyScopeResolver implements ScopeMetadataResolver {

    @Override
    public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
        ScopeMetadata result = new ScopeMetadata();
        result.setScopedProxyMode(ScopedProxyMode.NO);
        result.setScopeName("prototype");
        return result;
    }

}

MyTypeFilter.java

package se.waxwing.test;

import java.io.IOException;

import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.TypeFilter;

public class MyTypeFilter implements TypeFilter {

    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        return metadataReader.getClassMetadata().getClassName().equals(CustomBean.class.getCanonicalName());
    }
}

这会产生以下输出:

2009-aug-26 15:44:02 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c1b531: display name [org.springframework.context.support.ClassPathXmlApplicationContext@c1b531]; startup date [Wed Aug 26 15:44:02 CEST 2009]; root of context hierarchy
2009-aug-26 15:44:02 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [se/waxwing/test/Context.xml]
2009-aug-26 15:44:02 org.springframework.context.support.AbstractApplicationContext obtainFreshBeanFactory
INFO: Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@c1b531]: org.springframework.beans.factory.support.DefaultListableBeanFactory@121f1d
2009-aug-26 15:44:02 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@121f1d: defining beans [customBean,beanProcessor]; root of factory hierarchy
instantiating component
before customBean
after customBean

因此,正如您所看到的,customBean bean是由我的类型过滤器找到的,添加为bean,当调用applicationContext.getBean("customBean")时,实例化了一个新对象,然后将其传递给我发布bean处理器。

答案 1 :(得分:-1)

加载应用程序上下文后,检查您已注释的bean是否可用。

我怀疑,因为你已经关闭了“annotation-config”而忽略了你的注释。