最近研究了一下groovy,感觉语法很好玩
然后在springboot官网发现springboot支持groovy
于是,就突发奇想,如果我把controller全部用groovy写,然后用java把controller注册进去,岂不爽歪歪
网上查了很多资料,我看到最多的一段代码就是:
/**
* 注册Controller
* @param controllerBeanName
* @throws Exception
*/
public static void registerController(String controllerBeanName) throws Exception{
final RequestMappingHandlerMapping requestMappingHandlerMapping=
applicationContext.getBean(RequestMappingHandlerMapping.class);
if(requestMappingHandlerMapping!=null){
String handler=controllerBeanName;
Object controller= applicationContext.getBean(handler);
if(controller==null){
return;
}
//注册Controller
Method method=requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().
getDeclaredMethod("detectHandlerMethods",Object.class);
//将private改为可使用
method.setAccessible(true);
method.invoke(requestMappingHandlerMapping,handler);
}
}
看完,我属实大大的迷惑,难道,不应该是 xxx.regeist(name,xxx.class)这种类型么?
后来,经过一番研究,和各种查资料,终于解决了这个疑惑
原来,要注册一个controller需要经过两步
首先,需要将类注册成bean,然后再将这个bean通过上面那段代码注册成为controller
实例代码如下:
@Autowired
//我这里是将代码写到controller里的,所以直接自动注入了这个类
ApplicationContext applicationContext;
/**这段代码是groovy的风格java加分号就能用*/
GroovyClassLoader groovyLoader = new GroovyClassLoader()
Class<?> test = groovyLoader.parseClass('''这里是groovy的代码,或者用其它方式加载类''')
//将applicationContext转换为ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext
//获取BeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getAutowireCapableBeanFactory()
//创建bean信息.
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(test)
//动态注册bean.
defaultListableBeanFactory.registerBeanDefinition("forTest", beanDefinitionBuilder.getBeanDefinition())
final RequestMappingHandlerMapping requestMappingHandlerMapping=applicationContext.getBean(RequestMappingHandlerMapping.class)
//注册Controller
Method method=RequestMappingHandlerMapping.class.
getSuperclass().getSuperclass().
getDeclaredMethod("detectHandlerMethods",Object.class)
//将private改为可使用
method.setAccessible(true)
method.invoke(requestMappingHandlerMapping,"forTest")
经过以上步骤后,就完成了controller的动态注册