简体   繁体   中英

Spring `RestController` from `AbstractController` in TeamCity

The TeamCity plugin API allows adding controllers by extending their BaseController , which is a thin wrapper around Spring's AbstractController .

When I extend BaseController I can inject beans into the constructor in usual Spring manner. This is managed by a beans definition file like standard spring.,

To provide a Controller I must extend BaseController , override public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) , and add the controller to the beans definition. I register a URL route as part of constructor initialisation.

That's about all the extension points available to me for Controller.

I was hoping to be able to write small framework that would allow me to annotate my classes with @RestController and @RequestMapping , etc.

What I think I need to do is:

  • Wire up an annotation processor to find my controllers and their methods.
  • Build some sort of mapper which maps @RequestMapping annotated methods to routes
  • Wire up some content handlers, eg serialising/unserialising for JSON and XML
  • Dispatch incoming requests to the appropriate method inside my handleRequest method

Most of the above has already been written in Spring and Jersey, and I am wondering where I start researching that.

What classes provide the above functionality? I've tried a few things to try and instantiate MVC, but it seems to break when ApplicationContext is not available.

Not a TeamCity user. However I'll give my two cents, hoping for the best.
Being that you can register Spring Bean (s), why not trying out ClassPathBeanDefinitionScanner ?

If you have access somehow to a Spring lifecycle hook, an initialization one, or if you are able to register a Configuration class, you can create a Bean of type BeanFactoryPostProcessor . I'll give you a Java example, but you should be able to translate it to XML pretty quickly.

@Bean
public BeanFactoryPostProcessor beanFactoryPostProcessor(final ApplicationContext applicationContext) {
    return new BeanFactoryPostProcessor() {
        @Override
        public void postProcessBeanFactory(final ConfigurableListableBeanFactory beanFactory) throws BeansException {
            if (beanFactory instanceof BeanDefinitionRegistry) {
                try {
                    final BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                    final ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
                    scanner.setResourceLoader(applicationContext);
                    scanner.scan("your.base.package");
                } catch (final Exception e) {
                    // Handle
                }
            }
        }
    };
}

The ClassPathBeanDefinitionScanner will register all classes with Spring stereotype annotations.
You can also make a class implement the BeanFactoryPostProcessor interface directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM