sprng mvc + mybatis 完全注解配置, 零xml文件
写在前面
自从有了spring boot之后, 起一个web项目变的非常简单, 本篇文章主要讲解在不使用spring boot的自动配置的情况下, 如何使用spring mvc 搭建一个web项目 servlet3.0 后可以抛弃web.xml了, 所以本文也不会有任何xml文件, 全部使用`java config`的形式
创建项目
首先, 使用idea创建一个maven项目, 就叫 spring-web好了
使用spring mvc + mybatis + freemarker 搭建项目 spring.version=4.3.14.RELEASE 依赖的jar, 完整的 pom 文件如下:
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <exclusions> <exclusion> <artifactId>commons-logging</artifactId> <groupId>commons-logging</groupId> </exclusion> </exclusions> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.8</version> </dependency> <!-- freemarker --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.28</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency> <!-- database --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> </dependencies>
使用java配置
servlet 3.0 后, servlet 容器启动时会调用实现了ServletContainerInitializer接口的类,
spring mvc 的 SpringServletContainerInitializer实现了此接口, 在源码中可以看到实现中会循环调用WebApplicationInitializer的实现类
spring mvc 为了简化java的配置, 提供了AbstractAnnotationConfigDispatcherServletInitializer抽象类来简化配置, 虽然类名很长
新建一个配置类叫 WebAppInitializer, 继承上面那个名字很长的类⬆️
感觉这个就相当于之前的web.xml了, 如果以前熟悉spring web项目xml配置的同学, 很容易就能发现rootConfig 和 ServletConfig 很像之前的两个spring的 xml配置文件
如果需要配置其他 servlet 可以重写 onStartup()
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { // rootConfig 想当于之前的 application-context.xml @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringContextConfig.class}; } // servletConfig 相当于之前的 mvc-servlet.xml @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } // DispatchServlet 路径 @Override protected String[] getServletMappings() { return new String[]{"/*"}; } // 配置filters @Override protected Filter[] getServletFilters() { CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter(); encodingFilter.setEncoding(String.valueOf(StandardCharsets.UTF_8)); encodingFilter.setForceEncoding(true); return new Filter[]{encodingFilter}; } }
SpringContextConfig
这里可以配置数据源, 事务管理器, 启用注解扫描, 开启aop, 和其他框架集成(一般是orm框架, 这里我们使用mybatis)
是不是感觉很想之前的 application-context.xml里面的配置
PS: 如果 SpringMvcConfig 配置类在 SpringContextConfig 配置的包扫描下的话, 那需要将 SpringMvcConfig类排除掉, 要不然 SpringMvcConfig 类会初始化2次
@EnableAspectJAutoProxy @EnableTransactionManagement @PropertySource("classpath:application.properties") @ComponentScan(basePackages = {"cat.spring.web"}, excludeFilters = {@ComponentScan.Filter(classes = Controller.class), @ComponentScan.Filter(classes = EnableWebMvc.class)}) public class SpringContextConfig { @Bean public DataSource dataSource(Environment env) throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setJdbcUrl(env.getProperty("db.url")); dataSource.setDriverClass(env.getProperty("db.driver")); dataSource.setUser(env.getProperty("db.user")); dataSource.setPassword(env.getProperty("db.password")); dataSource.setMinPoolSize(Integer.valueOf(env.getProperty("pool.minPoolSize"))); dataSource.setMaxPoolSize(Integer.valueOf(env.getProperty("pool.maxPoolSize"))); dataSource.setAutoCommitOnClose(false); dataSource.setCheckoutTimeout(Integer.valueOf(env.getProperty("pool.checkoutTimeout"))); dataSource.setAcquireRetryAttempts(2); return dataSource; } /** * 配置事物管理器 * * @param dataSource * @retur */ @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * myBatis 配置 * * @param dataSource * @return */ @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(dataSource); sessionFactoryBean.setTypeAliasesPackage("cat.spring.web.entity"); sessionFactoryBean.setMapperLocations(new ClassPathResource[]{new ClassPathResource("/mapper/**/*.xml")}); Configuration configuration = new Configuration(); configuration.setUseGeneratedKeys(true); configuration.setMapUnderscoreToCamelCase(true); configuration.setUseColumnLabel(true); sessionFactoryBean.setConfiguration(configuration); return sessionFactoryBean; } @Bean public MapperScannerConfigurer mapperScannerConfigurer() { MapperScannerConfigurer configurer = new MapperScannerConfigurer(); configurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); configurer.setBasePackage("cat.spring.web.mapper"); return configurer; } }
给出 application.properties文件的配置
db.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true db.driver=com.mysql.jdbc.Driver db.user=root db.password=123456 #数据库连接池配置 #连接池中保留的最小连接数 pool.minPoolSize=5 #连接池中保留的最大连接数 pool.maxPoolSize=30 #获取连接超时时间 pool.checkoutTimeout=1000 freemarker.request-context-attribute=rc freemarker.expose-request-attributes=true freemarker.expose-session-attributes=true freemarker.prefer-file-system-access=false
SpringMvcConfig
SpringMvcConfig 主要配置spring mvc的拦截器, jsp或者freemarke等视图, 或者其他一些spring mvc 的配置
@EnableWebMvc @PropertySource("classpath:application.properties") @ComponentScan(basePackages = "cat.spring.web.controller", includeFilters = @ComponentScan.Filter(classes = Controller.class), useDefaultFilters = false) public class SpringMvcConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); } @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/index").setViewName("index"); } /** * 配置 freemarker * @return FreeMarkerConfigurer */ @Bean public FreeMarkerConfigurer freeMarkerConfigurer(Environment env) { FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); freeMarkerConfigurer.setTemplateLoaderPath("classpath:/templates/"); freeMarkerConfigurer.setPreferFileSystemAccess(env.getProperty("freemarker.prefer-file-system-access", boolean.class, false)); freeMarkerConfigurer.setDefaultEncoding(String.valueOf(StandardCharsets.UTF_8)); return freeMarkerConfigurer; } @Bean public ViewResolver freemarkerViewResolver(Environment env) { FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver("", ".ftl"); viewResolver.setViewClass(FreeMarkerView.class); viewResolver.setCache(false); viewResolver.setContentType("text/html;charset=utf-8"); viewResolver.setRequestContextAttribute(env.getProperty("freemarker.request-context-attribute", "rc")); viewResolver.setExposeRequestAttributes(env.getProperty("freemarker.expose-request-attributes", boolean.class, true)); viewResolver.setExposeSessionAttributes(env.getProperty("freemarker.expose-session-attributes", boolean.class, true)); return viewResolver; } }
运行
到这里项目配置部分就结束了, 我们可以使用maven 的tomecat插件运行
<build> <finalName>spring-web</finalName> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.0.0</version> </plugin> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.2</version> <configuration> <username>tomcat</username> <password>123456</password> <uriEncoding>utf-8</uriEncoding> <path>/cat</path> <port>8080</port> <update>false</update> <!--<warSourceDirectory>${basedir}/src/main/webapp</warSourceDirectory>--> </configuration> </plugin> </plugins> </build>
执行命令: mvn tomcat7:run