你可以通过在 Servlet 的 WebApplicationContext 中使用标准的 Spring Bean 定义来定义控制器 Bean。@Controller
允许自动检测,与 Spring 对检测 classpath 中的 @Component
类并为其自动注册 Bean 定义的一般支持保持一致。它也是注解类的一个 stereotype,表明它是一个 Web 组件。
为了实现对这种 @Controller
Bean 的自动检测,你可以在你的 Java 配置中添加组件扫描,如下例所示:
@Configuration
@ComponentScan("org.example.web")
public class WebConfig {
// ...
}
下面的例子显示了前述例子的 XML 等效配置:
<?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
是一个 组合的注解,它本身是由 @Controller 和 @ResponseBody 组成的元注解,表示一个控制器的每个方法都继承了类型级的 @ResponseBody
注解,因此,直接写入响应体,而不是用 HTML 模板进行视图解析和渲染。
AOP 代理
在某些情况下,你可能需要在运行时用 AOP 代理来装饰一个控制器。一个例子是,如果你选择在控制器上直接使用 @Transactional
注解。在这种情况下,对于控制器,我们建议使用 基于类的代理。这通常是控制器的默认选择。然而,如果一个控制器必须实现一个不是 Spring Context 回调的接口(如 InitializingBean
、*Aware
等),你可能需要明确配置基于类的代理。例如,对于 <tx:annotation-driven/>
,你可以改为<tx:annotation-driven proxy-target-class="true"/>
,对于 @EnableTransactionManagement
,你可以改为@EnableTransactionManagement(proxyTargetClass = true)
。