BeanPostProcessor не вызывается - PullRequest
       1

BeanPostProcessor не вызывается

2 голосов
/ 11 апреля 2011

вот мой 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.SampleDAO"/>
    </context:component-scan>

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

Я знаю, что при использовании компонентного сканирования область по умолчанию, которая будет назначена bean-компонентам, - это "singleton", если не указано иное в конфигурации xml или с использованием аннотации @Scope, это круто, но так как я поняла, из-за того, что в моем приложении все bean-компоненты, реализующие определенный интерфейс (com.coc.frmwk.cmd.Command), должны иметь свою область видимости «prototype», поэтому я добавил класс «ScopeResolver», который реализует ScopeMetaDataResolver, и я сделал это немного изменение моего config.xml, чтобы контейнер учитывал мой распознаватель области действия:

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

Моя проблема заключается в том, что BeanPostProcessor работал отлично, но он перестает вызываться всякий раз, когда я добавляю преобразователь области (context: component-scan base-package = "com" scope-resolver = "com.xxx. frmwk.processors.ScopeResolver "), и он снова работает, когда я опускаю содержимое жирным шрифтом.

Любая идея о том, как заставить BeanPostProcessor работать, когда ScopeResolver настроен? Спасибо, Мехди.

Редактировать: вот содержимое моего распознавателя области действия

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: Я хочу отметить, что на самом деле вызывается BeanPostProcessor, но, очевидно, он работает со всеми компонентами, кроме тех, чья область видимости была изменена ScopeMeteDataResolver.

Ответы [ 2 ]

3 голосов
/ 23 сентября 2013

Поведение, которое вы описываете, - это поведение, которое я ожидаю. (По крайней мере, при запуске), BeanPostProcessor вызывается, как только создается bean-компонент, bean-объект с прототипом создается только тогда, когда он запрашивается. Так что если вы не используете этот компонент нигде, BeanPostProcessor не будет вызван.

Однако, исходя из того, что вы хотите, вы хотите изменить рецепт (BeanDefinition, а не столько созданный экземпляр компонента). Для изменения рецептов вам необходимо использовать BeanFactoryPostProcessor.

Разница в том, что BeanPostProcessor работает с экземплярами бинов, тогда как BeanFactoryPostProcessor работает с рецептами создания бинов (BeanDefinitions).

1 голос
/ 14 апреля 2011

Я не нашел точно, как решить проблему, но я нашел обходной путь, это может быть полезно для любого, имеющего ту же проблему.
хорошо, вместо использования комбинации BeanPostProcessor и MetaDataScopeResolver, я решилиспользовать BeanFactoryPostProcessor, который управляет разрешением области и обработкой компонента.Вот код BeanFactoryPostProcessor для всех, кто заинтересован:

@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() + "]");
        }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...