Русский
Русский
English
Статистика
Реклама

Перевод Динамическое создание Spring Bean в рантайме

Перевод подготовлен специально для будущих студентов курса "Разработчик на Spring Framework".


Эта статья о динамическом создании бинов за пять лет стала самой популярной в моем блоге (более 9300 просмотров). Пришло время ее обновить. Также я добавил пример на Github.

динамика Spring Bean на Githubдинамика Spring Bean на Github

Однажды на тренинге меня спросили: "Можно ли создать Spring Bean динамически, чтобы можно было выбрать реализацию во время выполнения". Так как во время компиляции еще не известно, какой бин должен быть создан. Приложение должно решить это на основе properties-файла.

1. Создадим аннотацию для того, чтобы отметить метод, который должен создавать объект динамически:

package your.package;@Retention(RetentionPolicy.RUNTIME)public @interface InjectDynamicObject {}

2. Далее используем ее в методе, который должен создать объект:

@Servicepublic class CustomerServiceImpl {    private Customer dynamicCustomerWithAspect;        @InjectDynamicObject    public Customer getDynamicCustomerWithAspect() {        return this.dynamicCustomerWithAspect;    }}

3. Напишем аспект с Pointcut и Advise, который изменяет объект, возвращаемый методом на шаге 2:

@Component@Aspectpublic class DynamicObjectAspect {    // This comes from the property file    @Value("${dynamic.object.name}")    private String object;    @Autowired    private ApplicationContext applicationContext;        @Pointcut("execution(@com.lofi.springbean.dynamic.        InjectDynamicObject * *(..))")    public void beanAnnotatedWithInjectDynamicObject() {    }    @Around("beanAnnotatedWithInjectDynamicObject()")    public Object adviceBeanAnnotatedWithInjectDynamicObject(        ProceedingJoinPoint pjp) throws Throwable {           pjp.proceed();                // Create the bean or object depends on the property file          Object createdObject = applicationContext.getBean(object);        return createdObject;    }}

4. Пишем класс, который должен возвращаться из @InjectDynamicObject. Имя класса настраивается в properties-файле. В данном примере я написал две реализации Customer: CustomerOneImpl и CustomerTwoImpl:

@Component("customerOne")public class CustomerOneImpl implements Customer {    @Override    public String getName() {        return "Customer One";    }}application.propertiesdynamic.object.name=customerOne

5. Пишем тест:

@RunWith(SpringRunner.class)@SpringBootTestpublic class CustomerServiceImplTest {    @Autowired    private CustomerServiceImpl customerService;    @Test    public void testGetDynamicCustomerWithAspect() {        // Dynamic object creation        logger.info("Dynamic Customer with Aspect: " +            customerService.getDynamicCustomerWithAspect()            .getName());}

Но есть еще, более простой, способ сделать это. Без аспектов и AspectJ, только чистый Spring. Можно просто сохранить все реализации в Map и получить из нее необходимую реализацию. Так мы сделали в приложении eXTra Client. В качестве примера можно посмотреть на реализацию PluginsLocatorManager. Spring автомагически инжектит Map с именем бина (String) и самим бином.

" Даже типизированные Map можно инжектить автоматически, если тип ключа String. В значениях Map будут все бины ожидаемого типа, а в ключах соответствующие имена бинов".

Подробнее см. в документации Spring.

@Servicepublic class CustomerServiceImpl {        // We inject the customer implementations into a Map    @Autowired    private Map<String, Customer> dynamicCustomerWithMap;        // This comes from the property file as a key for the Map    @Value("${dynamic.object.name}")    private String object;    public Customer getDynamicCustomerWithMap() {        return this.dynamicCustomerWithMap.get(object);    }}

Подробнее о курсе "Разработчик на Spring Framework" можно узнать здесь.

Источник: habr.com
К списку статей
Опубликовано: 16.11.2020 18:23:29
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании otus. онлайн-образование

Программирование

Java

Spring beans

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru