2013-03-30 3 views
4

У меня есть несколько классов с пользовательской аннотацией, которые не должны быть созданы (абстрактный класс, и это всего лишь подкомпоненты для реального боба). Но в дополнение к этим классам, во время выполнения, на этапе инициализации контекста, я хочу добавить дополнительные компоненты в контекст приложения.Добавить пользовательские компоненты в контекст Spring

Итак, в основном мне нужно сканировать путь к классам, обрабатывать результаты и вводить новые компоненты в контекст приложения.

кажется, что весна-MVC, весна-задача и пружинная интеграция делают это (я пытался узнать его из источников - не повез)

я обнаружил, что я могу создать свои собственный BeanFactoryPostProcessor, путь к классам сканирований и звоните registerSingleton для моего пользовательского bean-компонента. Но я не уверен, что это хороший способ для введения новых bean-компонентов (кажется, что он используется только для постпроцесса извлечения только фасоли). И я считаю, что есть некоторые внутренние инструменты Spring, которые я могу повторно использовать для упрощения процесса.

Что такое обычный способ введения дополнительных компонентов в инициализацию контекста Spring?

+0

возможно это? Http: // StackOverflow.com/questions/520328/can-you-find-all-classes-in-a-package-using-reflection – noahlz

+0

Невозможно найти такие классы, я просто не знаю, как это сделать в фазе инициализации Sprign и как создать новый компонент для таких классов –

ответ

3

Ваше наблюдение на самом деле правильно, BeanFactoryPostProcessor является одним из двух способов Spring предоставляют механизм для изменения определения компонента/экземпляров, прежде чем сделать их доступными для приложения (другой использует BeanPostProcessors)

вы можете абсолютно использовать BeanFactoryPostProcessors добавлять/изменять определение фасоли, вот один пример из Spring Integration кодового, который добавляет errorChannel, если явно не указан пользователем, вы можете, вероятно, использовать подобный код для регистрации новых бобов:

RootBeanDefinition errorChannelDef = new RootBeanDefinition(); 
    errorChannelDef.setBeanClassName(IntegrationNamespaceUtils.BASE_PACKAGE 
      + ".channel.PublishSubscribeChannel"); 
    BeanDefinitionHolder errorChannelHolder = new BeanDefinitionHolder(errorChannelDef, 
      IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME); 
    BeanDefinitionReaderUtils.registerBeanDefinition(errorChannelHolder, registry); 
1

Есть по крайней мере два способа включения пользовательского аннотированные классов как бин:

  • аннотировать аннотации с @Component
  • Добавить включить фильтр типа аннотацией <context:component-scan/>

например:

<context:component-scan base-package="org.example"> 
     <context:include-filter type="annotation" expression="org.example.Annotation"/> 
</context:component-scan> 

Затем вы можете использовать BeanPostProcessor инстанцировать их, например:

public class CustomAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter 


     @Override 
      public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { 
       if (beanClass.isAnnotationPresent(org.example.Annotation.class)) { 
        Object bean = createBeanInstance(); 
        ... 
        return bean: 
       } 
       return null; 
      } 
    } 

Или использовать BeanFactoryPostProcessor для обработки ScannedGenericBeanDefinitions.

См. AnnotationConfigUtils.registerAnnotationConfigProcessors() для примера кода внутренних постпроцессоров.

Смежные вопросы