2015-07-31 5 views
0

У меня есть следующие компонентыКак зарегистрировать весенние бобы в контексте весны, из-за весеннего контекста?

  • Веб-приложение экспонируется с использованием Spring MVC (война файл).
  • Библиотека (jar-файл), которая осознает тот факт, что тот, кто пользуется библиотекой, использует весну.

Сценарий

Моя библиотека имеет класс, который должен зарегистрировать себя в качестве компонента в к контексту веб-приложений, не говоря пользователей библиотеки, чтобы изменить свой код (XML, контекст весна, или классы).

Так, другими словами, у меня есть класс и весенний контекст, я хочу, чтобы только из моего класса регистрировались в этом весеннем контексте, ничего не меняя в нем. Итак, есть ли время, когда весна сканирует путь к классам для классов, реализующих определенный интерфейс, если да, то какой интерфейс?

То, что я пытался

  • Использование BeanFactoryPostProcessor, но это требует, чтобы я получить доступ к контексту приложения и вызвать addBeanFactoryPostProcessor насколько я могу найти.

  • Использование ApplicationContextInitializer, но это заставляет меня изменить web.xml

  • кучу других вещей, таких как различные Aware интерфейсы, но я ничего не нашел еще, что позволяет мой класс самостоятельно зарегистрироваться на Bean Factory и подбираться в весеннем контексте, я хочу иметь возможность использовать такие вещи, как «Запланированная аннотация». И я всегда хочу, чтобы другие в весеннем контексте могли найти мой класс по автообновленной аннотации.

Примеры

класса, что у меня есть и внутри моей библиотеки

package spring.outside 

public class ClassA { 
    @Scheduled(fixedDelay=5000) 
    public void doSomething() { 
    } 
} 

Класс, который пользователь моей библиотеке владеет

package spring.inside 

public class ClassB { 
    @Autowired 
    private ClassA classA; 
} 

С пружинным файл, содержащий что-то вот так, что у меня нет

<context:component-scan base-package="spring.inside"/> 


Если это не представляется возможным Я хотел бы изучить возможности того, что я могу сделать в моем классе, который находится внутри весны до, так же легко, как это возможно, скажите контекст пружины забрать его.

Примеры

package spring.outside 

public class ClassA { 
    @Scheduled(fixedDelay=5000) 
    public void doSomething() { 
    } 
} 

класса, что пользователь моей библиотеке владеет

package spring.inside 

public class ClassB { 
    @Autowired 
    private ClassA classA; 
} 

Другой класс, который предназначен для инициирования CLASSA и поместить его в контекст весна приложения, я просто показать код некоторых из разных вещей, которые я тестировал сейчас, так как я не знаю, как это должно выглядеть.

package spring.inside 

public class ClassC implements BeanFactoryPostProcessor, ApplicationContextInitializer, BeanFactoryAware, ApplicationContextAware { 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     beanFactory.registerSingleton("classA", new ClassA()); 
    } 

    @Override 
    public void initialize(ConfigurableApplicationContext applicationContext) { 
     applicationContext.addBeanFactoryPostProcessor(this); 
    } 

    @Override 
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 
     ((ConfigurableListableBeanFactory)beanFactory).registerSingleton("classA", new ClassA()); 
    } 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
     ((ConfigurableApplicationContext)applicationContext.getParentBeanFactory()).addBeanFactoryPostProcessor(this); 
     ((ConfigurableListableBeanFactory)applicationContext.getParentBeanFactory()).registerSingleton("classA", new ClassA()); 
    } 
} 

Пытались

  • Добавление его с помощью BeanFactoryPostProcessor и registerSingleton
  • Добавление его с помощью ApplicationContextInitializer затем с помощью addBeanFactoryPostProcessor в комбинации с BeanFactoryPostProcessor
  • Добавление его BeanUtils.instantiate
  • Добавление его путем внедрения ApplicationContextAwa re и отбрасывая его в ConfigurableApplicationContext и добавляя реализацию BeanFactoryPostPrecessor, и я также попытался привести к ConfigurableListableBeanFactory и registerSingleton.
  • Добавление его с помощью BeanFactoryAware и registerSingleton.
  • Создание моего ClassC в конфигурации, в которой я добавляю компонент ComponScan для пакета spring.outside, работает отлично, но он чувствует себя очень неправильно, чтобы сделать это таким образом.

Но все это похоже на работу частично, но это всегда заканчивается тем, что получил некоторые ошибки синхронизации, такие как: ClassA потребности входных переменных в конструкторе, который Autowired внутри ClassC, некоторые из них устанавливаются при ClassC создает ClassA. Другой сценарий, который я видел, был ClassB, неспособный к Autowired ClassA, потому что это было сделано раньше. Итак, каков был бы правильный и хороший способ сделать это?

Я бег весенней версию 3.2.11.RELEASE

Если кто-нибудь знает, как решить эту проблему в хорошем способе, а не то, что чувствует себя как «уродливые взломать» Я был бы очень рад узнать, !

Спасибо и с наилучшими пожеланиями!

+0

вы пробовали использовать аннотацию компонента на ClassA? Я новичок в Spring, но я думаю, что Spring не может догадаться, что это за компонент, а что нет. –

+0

Чтобы использовать аннотацию компонентов, мне нужно выполнить компонентное сканирование этого пакета, что означает, что пользователю моей библиотеки придется либо добавить новый файл весны (мой, потому что я должен его создать), либо в свой контекст приложения, либо изменить собственный файл пружины на включите мой пакет в их сканирование компонентов. – nesohc

ответ

2

В этом случае вы должны включить CLASSA как весенний боб в весеннем контексте XML

<bean id="classA" class="spring.inside.ClassA"> 

или использовать класс по конфигурации

package spring.inside; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import spring.outside.ClassA; 

@Configuration 
public class AppConfiguration {  

    @Bean 
    ClassA classA() { 
     return new ClassA(); 
    } 
} 

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

  • Нет связанных вопросов^_^