我需要删除相应的Bean,然后添加另一个Bean,但是我发现springboot仅刷新注入的Bean一次
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>
only bootstrap.yml:
management:
endpoints:
web:
exposure:
include: '*'
endpoint:
health:
show-details: always
启动应用程序时,它将输出
[Users(name=hello0, age=23, gender=fe)]
,
然后通过POST访问该网址,
http://localhost:8080/actuator/refresh
它会输出
before remove:Users(name=hello0, age=23, gender=fe)
after:Users(name=hello1, age=23, gender=fe)
然后访问网址
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)
输出消息不是我们期望的。
如果在UsersController类中将@Autowired更改为@Resource,则应该是正常的。但在实际环境中可能为null,如果使用@Resource
,则应用程序将运行失败
我该如何解决这个问题?
感谢您的宝贵时间。
答案 0 :(得分:0)
@资源
@懒
可以正确启动应用程序。但这可能会导致错误,例如
ERROR [main] com.Users - No qualifying bean of type 'java.util.List<com.Users>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class java.lang.Object, mappedName=), @org.springframework.context.annotation.Lazy(value=true)}
答案 1 :(得分:0)
请查看文档的这一部分,以便在运行时刷新bean:https://cloud.spring.io/spring-cloud-static/Greenwich.SR1/single/spring-cloud.html#refresh-scope