我的一个 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
为关键词搜索,看起来有个比较靠谱的
第一个回答的话,我连在类上添加成员变量再 @Autowired 都不愿意,我还绕个大弯子设个 ApplicationContext 的成员变量,那不更加赘余了么。
第二个回答说使用 ApplicationContextAware 接口,这个接口的类会在 springboot 启动时被寻找,找到后会自动通知(注入) spring boot 的 ApplicationContext,我觉着应该就是这个了。虽然我觉得工具类还要我自己来写很不可思议(难道开发一个大型项目完全不会出现“一个 Bean 只在一个方法中被使用,为它添加一个成员变量没必要且逻辑混乱”这种情况么?) 然而这个接口的 setApplicationContext 方法居然不是静态方法?!一个工具类不应该都是不实例化的,通过调用静态方法来辅助解决问题的么?这个 setApplicationContext 方法不是静态的,那我 静态的 applicationContext 怎么注入啊。。。
而且我刚才两次搜索,完全没有搜到 ApplicationContextAware 这个接口的信息。应该以什么关键词去搜索,才能获得这种有用的信息呢?
谢谢
1
napsterwu 2019-08-24 12:37:02 +08:00
无解,就是要 Autowire 一个 context 或者 bean。或者可以在初始化之后把 context 注入到一个静态变量里。
|
2
anzu 2019-08-24 12:57:04 +08:00 1
后面没看。直接把 Autowire 写在方法参数中啊。
``` public String sayHello(@ Autowired HelloService service) { } ``` 这样,HelloService 就会自动绑定了。 |
3
CDuXZMAPgHp1q9ew 2019-08-24 13:19:34 +08:00 1
1. controller 是单例, 他持有的所有对象都是无状态的. 通常情况下减少一个类的成员变量的好处防止状态太多, 难易维护. 既然是无状态的, 注入进来又何妨.
2. 既然有洁癖, 为啥不一个接口一个 controller 呢 |
4
zhady009 2019-08-24 13:39:12 +08:00 1
@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); } } |
5
GM 2019-08-24 15:14:17 +08:00
ApplicationContextAware 是正解,里别的都是歪门邪道。
虽然 setApplicationContext 是实例方法,可是 java 并不禁止实例方法给静态属性赋值啊对吧,所以在把 setApplicationContext 注入的 context 存放到一个 static 变量里就可以了,然后就可以在别的静态方法里直接使用了。 |
6
Caelebs 2019-10-12 17:02:12 +08:00
身为菜鸡 只知道 ApplicationContextAware
|