开发者

BeanPostProcessor not called

here's my config.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/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com">
       <context:include-filter type="assignable" expression="com.coc.frmwk.cmd.Command"/>
       <context:include-filter type="assignable" expression="com.coc.apps.sample.dao.S开发者_JS百科ampleDAO"/>
    </context:component-scan>

<bean id="myPostProcessor" class="com.coc.frmwrk.processors.MyPostProcessor">
</beans>

I know that when using component-scan, the default scope that will be assigned to the beans is "singleton" unless it's specified otherwise in the xml configuration or using the annotation @Scope, that's cool, but since i've figured out that in my application all the beans implementing a specific interface (com.coc.frmwk.cmd.Command) need to have their scope set to "prototype", so i added a class "ScopeResolver" that implements ScopeMetaDataResolver and i made this little modification to my config.xml so that the container takes into account my scope resolver :

<context:component-scan base-package="com" scope-resolver="com.coc.frmwk.processors.ScopeResolver">

My problem is that the BeanPostProcessor used to work perfectly, but it stops being called whenever i add the scope resolver ( context:component-scan base-package="com" scope-resolver="com.xxx.frmwk.processors.ScopeResolver" ) and it works again when i omit the stuff in bold.

Any idea on how to make The BeanPostProcessor works when the ScopeResolver is configured ? Thanks, Mehdi.

Edit: here's the content of my scope resolver

package com.coc.frmwk.processors;

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

import com.coc.frmwk.cmd.Command;

public class ScopeResolver implements ScopeMetadataResolver{

    @SuppressWarnings("unchecked")
    @Override
    public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
        ScopeMetadata result = new ScopeMetadata();

        Class c= null;
        try {
            c = Class.forName(definition.getBeanClassName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        if (Command.class.isAssignableFrom(c))
        result.setScopeName("prototype");
        else
        result.setScopeName("singleton");

        System.out.println("[Scope Resolver] " + definition.getBeanClassName() + "[" + result.getScopeName() + "]");

        return result;
    }

}

Edit2: I want to point out that the BeanPostProcessor is in fact being called, but apparently it works with all the beans except those having their scope changed by the ScopeMeteDataResolver.


The behavior you describe is the behavior I would expect. (At least at startup), the BeanPostProcessor is called as soon as a bean is constructed, a prototype scoped bean is only constructed when it is requested. So if you don't use this bean anywhere the BeanPostProcessor will not get called.

However judging from what you want you want to modify the recipe (the BeanDefinition and not so much the created bean instance). For chancing the recipes you need to use a BeanFactoryPostProcessor.

The difference is that a BeanPostProcessor operates on bean instances where as the BeanFactoryPostProcessor works on the bean creation recipes (the BeanDefinitions).


I haven't found exactly how to solve the problem, but i did find a workaround, this might be useful for anyone having the same issue.
well instead of using a combination of BeanPostProcessor and a MetaDataScopeResolver, i decided to use a BeanFactoryPostProcessor that manages both the scope resolution and the bean processing. here'ds the code of the BeanFactoryPostProcessor for anyone interested:

@Component
public class OaliaBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @SuppressWarnings("unchecked")
    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {
        for(String beanName : beanFactory.getBeanDefinitionNames())
        {
            //Scope resolution
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
            Class beanClass= null;
            try {
                beanClass = Class.forName(beanDefinition.getBeanClassName());
            } catch (ClassNotFoundException e) {
                // exception handling goes here
            }
            if (Command.class.isAssignableFrom(beanClass))
                beanDefinition.setScope("prototype");

            //Stuff that the BeanPostProcessor do go here
            //..........
            //..........

            System.out.println("[Post Processing] " + beanName + " [" + beanDefinition.getScope() + "]");
        }
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜