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" />

Ответ 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");