sprng mvc + mybatis 完全注解配置, 零xml文件

写在前面

自从有了spring boot之后, 起一个web项目变的非常简单,
本篇文章主要讲解在不使用spring boot的自动配置的情况下, 如何使用spring mvc 搭建一个web项目
servlet3.0 后可以抛弃web.xml了, 所以本文也不会有任何xml文件, 全部使用`java config`的形式

创建项目

首先, 使用idea创建一个maven项目, 就叫 spring-web好了

sprng mvc + mybatis 完全注解配置, 零xml文件

使用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

相关推荐