如何在web应用里面配置spring

 人参与 | 时间:2026-10-17 06:53:23

Spring Boot 出现之后,应用很多人以为配置 Spring 就是配置改改 application.yml。但真实项目里,应用尤其是配置接手老系统时,你面对的应用可能还是那套经典的 XML 或 JavaConfig 体系。别慌,配置搞清楚核心逻辑,应用配置本质就三件事:告诉 Spring 去哪找 Bean、配置怎么创建 Bean、应用以及怎么把 Bean 之间的配置依赖关系串起来。

先说你最可能遇到的应用场景:一个 Servlet 容器里的 Web 应用。传统做法是配置配 web.xml,里面挂一个 ContextLoaderListener,应用再指定 Spring 的配置配置文件路径。比如这样:

<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> 

这玩意儿负责启动根容器,应用但它管不到 Controller。Spring MVC 的 DispatcherServlet 还得单独配一个自己的上下文。很多人栽在这里——两个容器并存,Service 在根容器里,Controller 在子容器里,子容器能看到父容器的 Bean,反过来不行。你要是把 Service 误配到子容器,启动时保准报 NoSuchBeanDefinitionException。

用 JavaConfig 的话,写法更干净。你写一个 @Configuration 类,上面标 @ComponentScan,Spring 会自动扫包。但注意,别把 @Configuration 类放在 Controller 所在包的最外层——扫描范围过大,可能把不该扫的接口实现类也拉进来,出一些莫名其妙的事务失效问题。

实际动手时,我建议你先从数据库连接池入手。Spring 的 DataSource 配置是绕不开的坎。用 HikariCP 的话,JavaConfig 里大概长这样:

@Bean public DataSource dataSource() {  HikariConfig config = new HikariConfig(); config.setJdbcUrl("jdbc:mysql://localhost:3306/test"); config.setUsername("root"); config.setPassword("password"); config.setMaximumPoolSize(20); return new HikariDataSource(config); } 

这里有个坑:连接池参数别写死在代码里。你可以用 @Value 注解从 properties 文件里读,或者更好一点,用 @ConfigurationProperties 绑定一个前缀。Spring Boot 里直接配 spring.datasource.hikari.* 就行,但传统 Spring 项目你得手动把环境变量映射进去。我见过一个老项目,DBA 改了数据库密码,开发找了半天才发现是 jdbc.properties 里写死了。

事务管理器也是 Web 应用标配。配好 DataSourceTransactionManager 之后,别忘了在配置类加 @EnableTransactionManagement,否则你 Service 上的 @Transactional 注解跟摆设一样。这个坑特别隐蔽——Spring 不会报错,只是事务不生效,数据写一半出了问题回滚不掉,排查起来费老劲。

视图解析器同样简单。InternalResourceViewResolver 配个前缀后缀,Controller 返回字符串就自动映射到 JSP。但你要是用 REST 风格接口,返回 JSON 就得加 @ResponseBody,或者配 MappingJackson2HttpMessageConverter。这里提醒一句:别为了省事把整个类标成 @RestController,除非你确定所有方法都返回 JSON。我见过有人图省事,结果某个方法想跳转页面,返回的字符串被当 JSON 序列化,浏览器直接下载了个 .json 文件。

最后说说 Filter 和拦截器的区别。Spring 的 DelegatingFilterProxy 可以把 Servlet Filter 委托给 Spring 管理的 Bean。配置编码过滤器时,注意 forceEncoding 参数要设成 true,否则只对请求生效,响应还是乱码。拦截器则要注册到 WebMvcConfigurer 里:

@Override public void addInterceptors(InterceptorRegistry registry) {  registry.addInterceptor(new LoginInterceptor()) .addPathPatterns("/admin/**") .excludePathPatterns("/admin/login"); } 

路径匹配规则容易出错,/** 和 /* 差一个层级,拦截范围天壤之别。写完之后用 curl 测几个边界路径,比看文档管用。

配置这活儿,说白了就是跟 Spring 的约定较劲。它默认帮你做了不少决定,但一旦你踩进自定义配置的深水区,就得自己负责把每个 Bean 的生命周期想清楚。我的经验是:先跑通最小可运行配置,再逐步加功能。别一上来就配 AOP 又配缓存,出了问题根本不知道是哪层配置炸的。你手头的应用要是还在用 Spring 4,升级到 5 的时候记得检查下 WebMvcConfigurerAdapter 是否被废弃,那个类在 Spring 5 里直接删了,编译期就会报错。

顶: 894踩: 83