You can define controller beans using the standard Spring bean definition in the WebApplicationContext servlet. The @Controller stereotype allows for automatic discovery, which correlates with Spring's general support for discovering classes marked with the @Component annotation in the classpath and automatically registering bean definitions for them. It also acts as a stereotype for the annotated class, indicating its role as a web component.

To enable automatic detection of such beans with the @Controller annotation, you can add component scanning to your Java configuration, as shown in the following example:

Java
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {
    // ...
}
Kotlin
@Configuration
@ComponentScan("org.example.web")
class WebConfig {
    // ...
}

The following example shows the XML equivalent of the configuration from the previous example:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="org.example.web"/>
    <!-- ... -->
</beans>

@RestController is a compound annotation that is itself meta-annotated with the @Controller and @ResponseBody annotations to denote the controller, each method which inherits the @ResponseBody annotation at the type level and therefore writes directly to the response body instead of recognizing the view and rendering it using an HTML template.

AOP Proxy

In some cases it may be necessary to decorate the AOP proxy controller at runtime. For example, if you decide to mark the controller itself with @Transactional annotations. In such cases, particularly for controllers, we recommend using class-based proxying. This is usually the default choice for controllers. However, if the controller must implement an interface that is not a Spring context callback (such as InitializingBean, *Aware, and others), you may need to explicitly configure class-based proxying. For example, with <tx:annotation-driven/> you can change it to <tx:annotation-driven proxy-target-class="true"/> , and with @EnableTransactionManagement you can change it to @EnableTransactionManagement(proxyTargetClass = true).