Spring автоустановка не работает из управляемого класса без spring
У меня есть класс (класс ABC), который создается путем вызова конструктора. Класс ABC, в свою очередь, имеет вспомогательный класс (класс XYZ), введенный с использованием автоматической проводки.
Наш - это приложение на основе MVC Spring, и я не вижу никаких исключений при запуске сервера.
Но я все еще вижу, что класс XYZ имеет значение null. Это из-за того, что класс ABC не создается экземпляром Spring Container?
В таких сценариях, как я могу использовать автоматическую проводку?
Спасибо.
Ответы
Ответ 1
Вы можете использовать этот способ для использования spring bean в классе spring bean
public class ApplicationContextUtils implements ApplicationContextAware {
private static ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext appContext)
throws BeansException {
ctx = appContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
}
теперь вы можете получить объект applicationcontext с помощью метода getApplicationContext().
из контекста приложения вы можете получить spring bean объекты следующим образом:
ApplicationContext appCtx = ApplicationContextUtils
.getApplicationContext();
String strFromContext = (String) appCtx.getBean(beanName);
Ответ 2
Автосообщение не будет работать, потому что класс ABC не управляется Spring. Вы можете сделать Spring управление ABC, используя одну из аннотаций @Component (@Component, @Service, @Controller и т.д.) Над определением класса, а затем используя контекст: компонентное сканирование в вашем контексте приложения XML или старое школы и просто определите bean непосредственно в контексте вашего приложения.
Если по какой-то причине вы не можете сделать Spring управлять классом ABC, вы можете загрузить контекст приложения в ABC, используя что-то вроде:
ApplicationContext context = новый ClassPaспасибоmlApplicationContext ( "путь/к/applicationContext.xml" );
а затем используйте:
XYZ someXyz = (XYZ) context.getBean( "MyXYZ" );
чтобы вручную установить значение bean.
Ответ 3
Правильно: вы не можете просто вызвать new
в классе и получить все его проводку; Spring должен управлять bean, чтобы он выполнял всю свою магию.
Если вы можете публиковать более подробную информацию о своем прецеденте, мы можем предложить полезные варианты.
Ответ 4
Вы можете использовать Spring @Configurable аннотацию в классе, который вы хотите использовать для autowire других beans.
Кроме того, вам нужно будет аннотировать любую конфигурацию bean с помощью @EnableSpringConfigured, чтобы Spring знал о вашем настраиваемом beans.
@EnableSpringКонфигурированная документация
public @interface EnableSpringConfigured Сигналы текущего контекста приложения для применения инъекции зависимостей к не управляемым классам, которые создаются вне Spring bean factory (обычно это классы, аннотированные с помощью @Configurable аннотации). Подобно функциональности, найденной в XML-элементе Spring. Часто используется в сочетании с @EnableLoadTimeWeaving.
@Configurable(autowire = Autowire.BY_TYPE)
public class ABC {
@Autowire private XYZ xyz;
...
}
@Configuration
@EnableSpringConfigured
public class Application {
...
}
public class MyClass {
public void doSomething() {
ABC abc = new ABC(); // XYZ is successfully autowired
...
}
}
Ответ 5
Короче говоря, да, ABC не получает инъекцию XYZ, потому что Spring не управляет ABC. Spring не может настроить объекты, о которых он не знает.
Вы можете управлять ABC, аннотируя его с помощью @Service
или @Component
. Обратите внимание, что для того, чтобы Spring взял эти аннотации, Spring должен включить автосканирование:
<context:component-scan base-package="com.mypackage.awesomeproject" />
Ответ 6
Первый вопрос - да, у вас есть null, потому что класс, не инициированный с помощью spring
Второй вопрос - я думаю, вы можете использовать поддержку aspectj http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-using-aspectj
Ответ 7
Вы можете аннотировать класс ABC
с аннотацией @Configurable
. Затем Spring IOC вводит экземпляр XYZ
в класс ABC
. Он обычно используется с AspectJ AnnotationBeanConfigurerAspect
.
Ответ 8
Для таких новичков, как я, которые выполняют базовую загрузку Spring и не знакомы с языком:
- Ваши Услуги, Репо и т.д. - все Бобы
- Вы можете получить свой Beans из ApplicationContext
Ашиш ответ работает для меня, но эта статья дает немного больше объяснений, imo.
Если вы не знаете имя нужного компонента, попробуйте поискать в этом массиве:
String[] names = context.getBeanDefinitionNames();
Если вас смущают разговоры о "компонентном сканировании" и файлах конфигурации, это может помочь узнать, что аннотация @SpringBootApplication (которую вы можете найти рядом с вашим методом main()) неявно вызывает @Configuration и @ComponentScan.
Это означает, что все файлы в этом пакете (объявленные в верхней части основного класса) выбираются Spring, и любые bean-компоненты, которые вы хотите добавить, могут быть записаны вместе с main()
Ответ 9
В ответ на ответ, предоставленный @Ashish Chaurasia, хотелось бы отметить, что решение является частичным. Класс ApplicationContextUtils
также должен быть пружинным компонентом, чтобы пружина вызывала приведенный ниже код.
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(ctx);
}
@Component
во главе класса сделает решение завершенным. Кроме того, есть еще один вариант сделать это с аннотацией @Autowired
.
@Component
public class ApplicationContextProvider {
private static ApplicationContext context;
public static ApplicationContext getApplicationContext() {
return context;
}
@Autowired
public void setContext(ApplicationContext context) {
ApplicationContextProvider.context = context;
}
}
Теперь к методу getBean
можно легко получить доступ -
ApplicationContextProvider.getApplicationContext().getBean("myBean");