Создания бинов с параметрами из базы данных и создания массива бинов и передачей этого массива как зависимость в другой бин.
Различные способы задания конфигурации Spring Beans (Java)
Различные способы задания конфигурации Spring Beans (Kotlin)
В задаче опроса филиалов в проекте МТС
Пример подмены bean в runtime для тестов
package ru.perm.v.vacancy_j.rest;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.test.web.servlet.MockMvc;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(EchoRest.class)
@Import(EchoRestLoggerTest.TestConfig.class)
public class EchoRestLoggerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private Logger logger; // Этот spring bean создается в TestConfig
// Пояснения по тесту:
// EchoRest создается полностью, штатно SpringBoot-ом и Logger объявлен через @Autowrired
// НО. Бин Loggerа создается в конфигурации EchoRestGigaTest.TestConfig
// Причем создается хитро, в runtime, через штатный метод с @Bean, @Primary (и это внедряется в контекст)
// НО!!! Этот бин создается как мок и его работу можно протестировать.
// УХХХХ!!!
// https://reflectoring.io/spring-boot-testconfiguration/
@Test
public void testEcho_NormalMessage_ReturnsSameMessage() throws Exception {
String message = "hello";
mockMvc.perform(get("/echo/" + message))
.andExpect(status().isOk())
.andExpect(content().string(message));
assertNotNull(logger);
logger.info("Echo message: {}", message);
org.mockito.Mockito.verify(logger).info("Echo message: {}", message);
}
@TestConfiguration
static class TestConfig {
// Генерация бина для тестирования
@Bean
@Primary
Logger logger() {
// Я хочу получить мок-объект, а не реальный бин.
return org.mockito.Mockito.mock(Logger.class);
}
}
}
Выполнение кода после иницализации и перед уничтожением bean:
@Component
public class DataLoader {
@Autowired
private UserRepository userRepository;
//method invoked during the startup
@PostConstruct
public void loadData() {
userRepository.save(new User("user"));
}
//method invoked during the shutdown
@PreDestroy
public void removeData() {
userRepository.deleteAll();
}
}
Инициализация bean и внесение в контекст SpringBoot:
@Configuration
public class HelloWorld {
@Bean
public TweetUserSevice tweetUserSevice() {
return new TweetUserSeviceImpl();
}
}
Ключевые моменты @Configuration и @Bean.
Еще примеры:
package com.ronak.tweet.beans;
@Configuration
@Order(value=1)
@Import({
TweetBeansConfig.class,
TweetSystemHealthBeansConfig.class
})
public class TweetMasterSpringConfig {
public TweetMasterSpringConfig() {
System.out.println("Initilaizing master spring config");
}
}
package ru.perm.v.beans;
@Configuration
public class BeanOneConfig {
@Bean
public BeanOne createBeanOne() {
return new BeanOne();
}
}
@Configuration
public class BeanTwoConfig {
@Bean
public BeanTwo createBeanTwo() {
return new BeanTwo();
}
}
Main class
package ru.perm.v.app;
@SpringBootApplication
public class DemoApplication extends SpringBootServletInitializer {
@Bean
ResourceConfig resourceConfig() {
return new ResourceConfig().packages("ru.perm.v.beans");
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class);
}
}
Использование в РЕАЛЬНОМ проекте
https://github.com/cherepakhin/vacancy_backend_j/blob/auth/src/main/java/ru/perm/v/vacancy_j/conf/CreatorExtListSite.java
Ссылки:
Динамическое создание Spring Bean в рантайме(habr)
Spring - Dynamically register beans in 4 ways At Run-Time
How to Dynamically Autowire a Bean in Spring
Changing Spring Boot Properties at Runtime