请问 Springboot 有没有什么优雅的方法可以调用 getBean(String beanname) 来获取 Bean?

2019-08-24 11:57:25 +08:00
 Newyorkcity

我的一个 controller 中想要调用一个 Bean,因为整个 controller 只有一个方法用到了它,所以我不希望在 controller 里声明一个成员变量然后注释 @Autowired,而希望在那个方法中用 applicationContext.getBean(...) 这样的方法得到它....

我知道 ApplicationContextAware 这个接口,但我真心觉得这个接口设计的很奇怪。请见下文的最后。

下文是我为解决这个问题做了啥,免得有人吐槽我伸手党。


所以我先以 getbean inurl:docs.spring.io/spring-boot/ 为关键词,试图找到相关的官网资料,无果..

再以 get applicationcontext inurl:docs.spring.io/spring-boot/ 为关键词搜索,还是没有相关的官网资料

好吧,那看看 stackoverflow.com 上会不会已经有同样的问题了,以 how to getBean Springboot inurl:stackoverflow.com 为关键词搜索,看起来有个比较靠谱的

https://stackoverflow.com/questions/34088780/how-to-get-bean-using-application-context-in-spring-boot/38274721

第一个回答的话,我连在类上添加成员变量再 @Autowired 都不愿意,我还绕个大弯子设个 ApplicationContext 的成员变量,那不更加赘余了么。

第二个回答说使用 ApplicationContextAware 接口,这个接口的类会在 springboot 启动时被寻找,找到后会自动通知(注入) spring boot 的 ApplicationContext,我觉着应该就是这个了。虽然我觉得工具类还要我自己来写很不可思议(难道开发一个大型项目完全不会出现“一个 Bean 只在一个方法中被使用,为它添加一个成员变量没必要且逻辑混乱”这种情况么?) 然而这个接口的 setApplicationContext 方法居然不是静态方法?!一个工具类不应该都是不实例化的,通过调用静态方法来辅助解决问题的么?这个 setApplicationContext 方法不是静态的,那我 静态的 applicationContext 怎么注入啊。。。

而且我刚才两次搜索,完全没有搜到 ApplicationContextAware 这个接口的信息。应该以什么关键词去搜索,才能获得这种有用的信息呢?

谢谢

6688 次点击
所在节点    问与答
6 条回复
napsterwu
2019-08-24 12:37:02 +08:00
无解,就是要 Autowire 一个 context 或者 bean。或者可以在初始化之后把 context 注入到一个静态变量里。
anzu
2019-08-24 12:57:04 +08:00
后面没看。直接把 Autowire 写在方法参数中啊。
```
public String sayHello(@ Autowired HelloService service) { }
```
这样,HelloService 就会自动绑定了。
wujichao
2019-08-24 13:19:34 +08:00
1. controller 是单例, 他持有的所有对象都是无状态的. 通常情况下减少一个类的成员变量的好处防止状态太多, 难易维护. 既然是无状态的, 注入进来又何妨.
2. 既然有洁癖, 为啥不一个接口一个 controller 呢
zhady009
2019-08-24 13:39:12 +08:00
@Bean
public SpringBeanUtil getSpringBeanUtil(ApplicationContext applicationContext) {
SpringBeanUtil springBeanUtil = new SpringBeanUtil();
springBeanUtil.setApplicationContext(applicationContext);
return springBeanUtil;
}


public class SpringBeanUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext;

public void setApplicationContext(ApplicationContext appContext) throws BeansException {
applicationContext = appContext;
}

@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
return (T) applicationContext.getBean(name);
}

public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
}
GM
2019-08-24 15:14:17 +08:00
ApplicationContextAware 是正解,里别的都是歪门邪道。

虽然 setApplicationContext 是实例方法,可是 java 并不禁止实例方法给静态属性赋值啊对吧,所以在把 setApplicationContext 注入的 context 存放到一个 static 变量里就可以了,然后就可以在别的静态方法里直接使用了。
Caelebs
2019-10-12 17:02:12 +08:00
身为菜鸡 只知道 ApplicationContextAware

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/594708

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX