Как получить bean-компонент с использованием контекста приложения при загрузке весны

Я занимаюсь разработкой проекта SpringBoot и хочу получить компонент по имени с помощью applicationContext. Я пробовал многие решения из Интернета, но не смог добиться успеха. Мое требование заключается в том, что у меня есть контроллер

ControllerA

и внутри контроллера у меня есть метод getBean(String className). Я хочу получить экземпляр зарегистрированного боба. У меня есть спящие сущности, и я хочу получить экземпляр компонента, передавая имя класса только в методе getBean.

Пожалуйста, помогите, если кто-то знает решение.

Ответ 1

Вы можете Autowire ApplicationContext, либо в качестве поля

@Autowired
private ApplicationContext context;

или метод

@Autowired
public void context(ApplicationContext context) { this.context = context; }

Наконец, используйте

context.getBean(SomeClass.class)

Ответ 2

Вы можете использовать ApplicationContextAware.

ApplicationContextAware:

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

Существует несколько способов получения ссылки на контекст приложения. Вы можете реализовать ApplicationContextAware, как в следующем примере:

package hello;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    } 

 public ApplicationContext getContext() {
        return applicationContext;
    }

}

Обновить:

Когда Spring создает экземпляры bean-компонентов, он ищет реализации ApplicationContextAware. Если они будут найдены, будут вызваны методы setApplicationContext().

Таким образом, Spring устанавливает текущий контекст приложения.

Фрагмент кода из source code Spring:

private void invokeAwareInterfaces(Object bean) {
        .....
        .....
 if (bean instanceof ApplicationContextAware) {                
  ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
   }
}

Как только вы получите ссылку на контекст приложения, вы получите выборку bean-компонента по вашему желанию с помощью getBean().

Ответ 3

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

в классе обслуживания

@Autowired
private ApplicationContext context;

SomeClass sc = (SomeClass)context.getBean(SomeClass.class);

теперь в ссылке sc у вас есть объект. Надеюсь, объяснил хорошо. Если есть сомнения, пожалуйста, дайте мне знать.

Ответ 4

Если вы находитесь внутри Spring bean (в данном случае компонента @Controller), вы не должны использовать экземпляр контекста Spring вообще. Просто напрямую className атрибут className.

BTW, избегайте использования инъекции на месте, поскольку это считается плохой практикой.

Ответ 5

Вы можете использовать класс ApplicationContextAware, который может предоставить контекст приложения.

public class ApplicationContextProvider implements ApplicationContextAware {

    private static ApplicationContext ctx = null;

    public static ApplicationContext getApplicationContext() {
        return ctx;
    }

    @Override
    public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
        ApplicationContextProvider.ctx = ctx;
    }

    /**
     * Tries to autowire the specified instance of the class if one of the specified
     * beans which need to be autowired are null.
     *
     * @param classToAutowire        the instance of the class which holds @Autowire
     *                               annotations
     * @param beansToAutowireInClass the beans which have the @Autowire annotation
     *                               in the specified {#classToAutowire}
     */
    public static void autowire(Object classToAutowire, Object... beansToAutowireInClass) {
        for (Object bean : beansToAutowireInClass) {
            if (bean == null) {
                ctx.getAutowireCapableBeanFactory().autowireBean(classToAutowire);
            }
        }
    }

}

Ответ 6

Просто используйте:

org.springframework.beans.factory.BeanFactory#getBean(java.lang.Class)

Пример:

@Component
public class Example {

    @Autowired
    private ApplicationContext context;

    public MyService getMyServiceBean() {
        return context.getBean(MyService.class);
    }

    // your code uses getMyServiceBean()
}

Ответ 7

Вы можете использовать ServiceLocatorFactoryBean. Сначала вам нужно создать интерфейс для вашего класса

public interface YourClassFactory {
    YourClass getClassByName(String name);
}

Затем вы должны создать файл конфигурации для ServiceLocatorBean

@Configuration
@Component
public class ServiceLocatorFactoryBeanConfig {

    @Bean
    public ServiceLocatorFactoryBean serviceLocatorBean(){
        ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
        bean.setServiceLocatorInterface(YourClassFactory.class);
        return bean;
    }
}

Теперь вы можете найти свой класс по имени, как это

@Autowired
private YourClassfactory factory;

YourClass getYourClass(String name){
    return factory.getClassByName(name);
}