У меня есть требование удалить соответствующий Бин и затем добавить другой Бин, но я считаю, что Springboot обновляет введенный Бин только один раз
версия для Springboot - 2.1.5. RELEASE, JDK1.8
public class Users {
String name;
int age;
String gender;
public Users() {
}
public Users(String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
}
@Component
public class UsersController implements ApplicationRunner {
@Autowired(required = false)
// @Resource
List<Users> users= Collections.emptyList();
@Override
public void run(ApplicationArguments args) {
System.out.println(users);
}
}
@RestController
public class HelloController implements
BeanDefinitionRegistryPostProcessor, ApplicationContextAware {
ApplicationContext applicationContext;
DefaultListableBeanFactory defaultListableBeanFactory;
Users users;
int i=0;
@RequestMapping("/hello1")
public String index1() {
return "hello";
}
@RequestMapping("/hello3")
public Users index3() {
UsersController controller =
applicationContext.getBean(UsersController.class);
controller.run(null);
return null;
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry
registry) throws BeansException {
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory
beanFactory) throws BeansException {
defaultListableBeanFactory= (DefaultListableBeanFactory)
beanFactory;
Users users=new Users("hello"+(i++),23,"fe");
this.users=users;
defaultListableBeanFactory.registerBeanDefinition(users.getName(),
BeanDefinitionBuilder.genericBeanDefinition(Users.class, () ->
users).getRawBeanDefinition());
}
@EventListener
public void onApplicationEvent(@NonNull EnvironmentChangeEvent
environmentChangeEvent) {
System.out.println("before
remove:"+applicationContext.getBean(Users.class));
defaultListableBeanFactory.removeBeanDefinition(users.getName());
Users users=new Users("hello"+(i++),23,"fe");
this.users=users;
defaultListableBeanFactory.registerBeanDefinition(users.getName(),
BeanDefinitionBuilder.genericBeanDefinition(Users.class,
() -> users).getRawBeanDefinition());
System.out.println("after:"+applicationContext.getBean(Users.class));
}
@Override
public void setApplicationContext(ApplicationContext
applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
}
pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
</dependencies>
только bootstrap.yml:
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
при запуске приложения оно выдаст
[Users(name=hello0, age=23, gender=fe)]
,
а затем посетите URL по почте,
http://localhost:8080/actuator/refresh
это будет выводить
before remove:Users(name=hello0, age=23, gender=fe)
after:Users(name=hello1, age=23, gender=fe)
затем посетите URL
http://localhost:8080/hello3
выход
[Users(name=hello1, age=23, gender=fe)]
Этого следовало ожидать, если посетить URL еще раз
http://localhost:8080/actuator/refresh
выход
before remove:Users(name=hello1, age=23, gender=fe)
after:Users(name=hello2, age=23, gender=fe)
Этого также следовало ожидать, но посетите URL
http://localhost:8080/hello3
мы надеемся, что выходной
Users(name=hello2, age=23, gender=fe)
но это вывод
Users(name=hello1, age=23, gender=fe)
Выходное сообщение не соответствует ожиданиям.
Если изменить @Autowired на @Resource в классе UsersController, оно должно быть нормальным. Но в реальной среде это может быть ноль, приложение будет работать неуспешно, если использовать @Resource
Как я могу решить эту проблему?
Спасибо за ваше время.