[Программирование, Java] Динамическое создание Spring Bean в рантайме (перевод)  
    
    
        
    
    
    
    
            
    
        
            
                
                                    
                
                                    
                
                    
                
            
        
    
    
        
            
                
                
                    
                         
                         
                       
                    
                        Автор 
                        Сообщение 
                    
                                        
                        
                            
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                        
                                                                                                                
                                            Сообщений: 27286                                        
                                                                                                                                                
                                                             
                            
                                
                             
                         
                        
                            
                                
                                    
                                        
                                        
Перевод подготовлен специально для будущих студентов курса "Разработчик на Spring Framework".

Эта статья о динамическом создании бинов за пять лет стала самой популярной в моем блоге (более 9300 просмотров). Пришло время ее обновить. Также я добавил пример на Github.
динамика Spring Bean на GithubОднажды на тренинге меня спросили: "Можно ли создать Spring Bean динамически, чтобы можно было выбрать реализацию во время выполнения". Так как во время компиляции еще не известно, какой бин должен быть создан. Приложение должно решить это на основе properties-файла. 1. Создадим аннотацию для того, чтобы отметить метод, который должен создавать объект динамически:
package your.package;
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectDynamicObject {
}
2. Далее используем ее в методе, который должен создать объект:
@Service
public class CustomerServiceImpl {
    private Customer dynamicCustomerWithAspect;
    @InjectDynamicObject
    public Customer getDynamicCustomerWithAspect() {
        return this.dynamicCustomerWithAspect;
    }
}
3. Напишем аспект с Pointcut и Advise, который изменяет объект, возвращаемый методом на шаге 2:
@Component
@Aspect
public 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.properties
dynamic.object.name=customerOne
5. Пишем тест:
@RunWith(SpringRunner.class)
@SpringBootTest
public 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.
@Service
public 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
===========
===========
 Автор оригинала: Dr. Lofi Dewanto
===========Похожие новости:
- [Разработка игр, Тестирование игр] Тестирование игр (перевод)
 
- [Программирование, C++, C, Программирование микроконтроллеров] Включаем периферию контроллера за 1 такт или магия 500 строк кода
 
- [Разработка веб-сайтов, CSS, JavaScript, Программирование, HTML] Современный стартовый HTML-шаблон
 
- [Программирование, C++, ООП, Профессиональная литература] О C++ и объектно-ориентированном программировании (перевод)
 
- [JavaScript, VueJS] CSR vs SSR для одностраничных приложений на VueJS
 
- [Тестирование IT-систем, JavaScript, Google Chrome] Автотесты на базе playwright и jest
 
- [Тестирование IT-систем, Java, Apache] Сбор данных и отправка в Apache Kafka
 
- [Java] Обеспечение границ компонент чистой архитектуры с помощью Spring Boot и ArchUnit (перевод)
 
- [Программирование, Анализ и проектирование систем, Разработка систем связи, Гаджеты, Научно-популярное] JS8Call: Slack на коротких волнах
 
- [Программирование, Java] Обработка исключений в контроллерах Spring
 
Теги для поиска: #_programmirovanie (Программирование), #_java, #_spring_beans, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_programmirovanie (
Программирование
), #_java
                                        
                                        
                                        
                                     
                                    
                                    
                                                                    
                                                                                             
                         
                        
                            
                                                                    
                                                             
                         
                    
                    
                
                
            
        
    
    
    
    
    
            
    
            
    
        
    
    
        
                        Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    
    
        
        Текущее время: 04-Ноя 14:07
Часовой пояс: UTC + 5 
            
    
                
| Автор | Сообщение | 
|---|---|
| 
                                
                                
                                                                                                            news_bot ®
                                                                        
                                                                                                                                                 
                                                                            
                                                                                                                
                                            Стаж: 7 лет 8 месяцев                                          | 
                            |
| 
                                 Перевод подготовлен специально для будущих студентов курса "Разработчик на Spring Framework". 
![]() Эта статья о динамическом создании бинов за пять лет стала самой популярной в моем блоге (более 9300 просмотров). Пришло время ее обновить. Также я добавил пример на Github. ![]() динамика Spring Bean на GithubОднажды на тренинге меня спросили: "Можно ли создать Spring Bean динамически, чтобы можно было выбрать реализацию во время выполнения". Так как во время компиляции еще не известно, какой бин должен быть создан. Приложение должно решить это на основе properties-файла. 1. Создадим аннотацию для того, чтобы отметить метод, который должен создавать объект динамически: package your.package; 
@Retention(RetentionPolicy.RUNTIME) public @interface InjectDynamicObject { } @Service 
public class CustomerServiceImpl { private Customer dynamicCustomerWithAspect; @InjectDynamicObject public Customer getDynamicCustomerWithAspect() { return this.dynamicCustomerWithAspect; } } @Component 
@Aspect public 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; } } @Component("customerOne") 
public class CustomerOneImpl implements Customer { @Override public String getName() { return "Customer One"; } } application.properties dynamic.object.name=customerOne @RunWith(SpringRunner.class) 
@SpringBootTest public class CustomerServiceImplTest { @Autowired private CustomerServiceImpl customerService; @Test public void testGetDynamicCustomerWithAspect() { // Dynamic object creation logger.info("Dynamic Customer with Aspect: " + customerService.getDynamicCustomerWithAspect() .getName()); } "… Даже типизированные Map можно инжектить автоматически, если тип ключа String. В значениях Map будут все бины ожидаемого типа, а в ключах — соответствующие имена бинов". 
@Service 
public 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 =========== =========== Автор оригинала: Dr. Lofi Dewanto ===========Похожие новости: 
 Блог компании OTUS. Онлайн-образование ), #_programmirovanie ( Программирование ), #_java  | 
                        |
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
    Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 04-Ноя 14:07
Часовой пояс: UTC + 5