spring4.3+mybatis3.4+freemark+log4j2+fastjson整合
2017-7-1 更新 spring 版本 4.3.9 更新mybatis 为3.4.3
0、先写下文件结构防止配置放错地方
1、首先发下maven配置
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> <!--依赖版本--> <spring.version>4.3.9.RELEASE</spring.version> <mybatis.version>3.4.4</mybatis.version> <javax.servlet.version>3.1.0</javax.servlet.version> <freemarker.version>2.3.23</freemarker.version> <junit.version>4.12</junit.version> <mybatis-spring.version>1.3.1</mybatis-spring.version> <log4j2.version>2.8.2</log4j2.version> <slf4j.version>1.7.21</slf4j.version> <fastjson.version>1.2.35</fastjson.version> <guava.version>22.0</guava.version> <druid-version>1.0.31</druid-version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-framework-bom</artifactId> <version>${spring.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!--spring框架相关配置 begin--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${javax.servlet.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> <!--<dependency>--> <!--<groupId>com.fasterxml.jackson.core</groupId>--> <!--<artifactId>jackson-databind</artifactId>--> <!--<version>2.6.4</version>--> <!--</dependency>--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!--spring框架相关配置 end--> <!--freemarker begin--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>${freemarker.version}</version> </dependency> <!--freemarker end--> <!--orm and db begin--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis-spring.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.42</version> <scope>runtime</scope> </dependency> <dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>sqljdbc4</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid-version}</version> </dependency> <!--orm and db end--> <!--日志 begin--> <dependency> <!-- 桥接:告诉Slf4j使用Log4j2 --> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <!-- 桥接:告诉commons logging使用Log4j2 --> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>${log4j2.version}</version> </dependency> <!--日志 end--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.6</version> </dependency> <!--工具包 begin--> <!--<dependency>--> <!--<groupId>org.apache.commons</groupId>--> <!--<artifactId>commons-collections4</artifactId>--> <!--<version>4.1</version>--> <!--</dependency>--> <!--<dependency>--> <!--<groupId>joda-time</groupId>--> <!--<artifactId>joda-time</artifactId>--> <!--<version>2.9.1</version>--> <!--</dependency>--> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>${guava.version}</version> </dependency> <!--工具包 end--> <!--测试包 begin--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <scope>test</scope> </dependency> <!--测试包 end--> </dependencies> <build> <!--<finalName>test</finalName>--> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <executions> <execution> <id>Generate MyBatis Artifacts</id> <goals> <goal>generate</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>utf8</encoding> </configuration> </plugin> </plugins> </build>
简单说明以下包的作用:
spring-web 是对servlet的封装 核心包
spring-webmvc 是在spring-web的基础上添加mvc支持 例如v层适配,这里freemark模板引擎就用到了其中的 org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver类
spring-context-support 是对常用bean的扩展 其中 FreeMarkerConfigurer会依赖此包的 org.springframework.ui.freemarker.FreeMarkerConfigurationFactory
javax.servlet-api 是核心api这里使用3.1
spring-aspects 提供对AspectJ的支持
spring-tx 对事物支持 @Transactional 就在此包中
spring-jdbc 对jdbc的封装,方便spring管理jdbc 该项目中事物的管理便是使用了 org.springframework.jdbc.datasource.DataSourceTransactionManager
fastjson 这个包是用来处理返回json数据问题 来自阿里值得信赖
2、然后是 web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <!-- 区分项目名称,防止默认重名 --> <context-param> <param-name>webAppRootKey</param-name> <param-value>maven.xxl_web.root</param-value> </context-param> <!-- 字符集 过滤器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 设置Spring容器加载配置文件路径 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-*.xml</param-value> </context-param> <!-- Spring view分发器 --> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> <!--拦截/*,这是一个错误的方式,请求可以走到Action中,但转到jsp时再次被拦截,不能访问到jsp。 拦截/,restful风格 弊端:会导致静态文件(jpg,js,css)被拦截后不能正常显示。解决办法看dispatcher--> </servlet-mapping> <!-- Spring会创建一个WebApplicationContext上下文,称为父上下文(父容器) ,保存在 ServletContext中,key是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值。 可以使用Spring提供的工具类取出上下文对象:WebApplicationContextUtils.getWebApplicationContext(ServletContext); DispatcherServlet是一个Servlet,可以同时配置多个,每个 DispatcherServlet有一个自己的上下文对象(WebApplicationContext),称为子上下文(子容器),子上下文可以访问父上下文中的内容, 但父上下文不能访问子上下文中的内容。 它也保存在 ServletContext中,key是"org.springframework.web.servlet.FrameworkServlet.CONTEXT"+Servlet名称。当一个Request对象产生时, 会把这个子上下文对象(WebApplicationContext)保存在Request对象中,key是DispatcherServlet.class.getName() + ".CONTEXT"。 可以使用工具类取出上下文对象:RequestContextUtils.getWebApplicationContext(request);--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- log4j2-begin --> <!-- 注意! 由于使用3.1版本web.xml log4j2 会自动注册 如果使用2.5版本xml 需要手动注册 以下代码--> <!--<listener>--> <!--<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>--> <!--</listener>--> <!--<filter>--> <!--<filter-name>log4jServletFilter</filter-name>--> <!--<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>--> <!--</filter>--> <!--<filter-mapping>--> <!--<filter-name>log4jServletFilter</filter-name>--> <!--<url-pattern>/*</url-pattern>--> <!--<dispatcher>REQUEST</dispatcher>--> <!--<dispatcher>FORWARD</dispatcher>--> <!--<dispatcher>INCLUDE</dispatcher>--> <!--<dispatcher>ERROR</dispatcher>--> <!--</filter-mapping>--> <!-- log4j2-end --> </web-app>
ps:没什么说的 使用restfull风格 因为这样可以灵活控制以什么结尾
3、下面是dispatcher的spring配置(这个配置是view层相关的,配置了freemark模板引擎和静态文件)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--配置json适配器--> <mvc:annotation-driven> <mvc:message-converters> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4" p:fastJsonConfig-ref="fastJsonConfig"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig"> <property name="serializerFeatures"> <list> <value>WriteMapNullValue</value> <value>QuoteFieldNames</value> </list> </property> </bean> <!--注解说明 <context:annotation-config />--> <!-- @Controller 声明Action组件 @Service 声明Service组件 @Service("myMovieLister") @Repository 声明Dao组件 @Component 泛指组件, 当不好归类时. @RequestMapping("/menu") 请求映射 @Resource 用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName") @Autowired 用于注入,(spring提供的) 默认按类型装配 @Transactional( rollbackFor={Exception.class}) 事务管理 @ResponseBody @Scope("prototype") 设定bean的作用域 --> <context:component-scan base-package="com.test.app.controller" /> <mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/> <mvc:resources mapping="/js/**" location="/js/" cache-period="31556926"/> <mvc:resources mapping="/css/**" location="/css/" cache-period="31556926"/> <!-- freemarker的配置 --> <bean id="freemarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> <property name="templateLoaderPath" value="/WEB-INF/view/" /> <property name="defaultEncoding" value="UTF-8" /> <property name="freemarkerSettings"> <props> <prop key="template_update_delay">10</prop> <prop key="locale">zh_CN</prop> <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop> <prop key="date_format">yyyy-MM-dd</prop> <prop key="number_format">#.##</prop> </props> </property> </bean> <!-- FreeMarker视图解析 在这里配置后缀名ftl和视图解析器。。 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> <property name="suffix" value=".ftl" /> <property name="contentType" value="text/html;charset=UTF-8" /> <property name="exposeRequestAttributes" value="true" /> <property name="exposeSessionAttributes" value="true" /> <property name="exposeSpringMacroHelpers" value="true" /> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="i18n/messages" /> </beans>
4、下面发下applicationContext-bean.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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <context:component-scan base-package="com.test.app"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 使用annotation注解方式配置事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 使用JDBC事务 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 引入配置文件 --> <context:property-placeholder location="classpath:ini.properties"/> <!--创建jdbc数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> <property name="maxIdle" value="${maxIdle}"/> <property name="minIdle" value="${minIdle}"/> </bean> <!-- 配置SqlSessionFactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis.xml"/> <property name="mapperLocations" value="classpath:mapper/*.xml"/> </bean> <!-- 配置mybatis dao注册,所有dao都继承sqlMapper annotationClass:当指定了annotationClass的时候,MapperScannerConfigurer将只注册使用了annotationClass注解标记的接口。 markerInterface:markerInterface是用于指定一个接口的,当指定了markerInterface之后,MapperScannerConfigurer将只注册继承自markerInterface的接口。 如果上述两个属性都指定了的话,那么MapperScannerConfigurer将取它们的并集,而不是交集。即使用了annotationClass进行标记或者继承自markerInterface 的接口都将被注册为一个MapperFactoryBean。 除了用于缩小注册Mapper接口范围的属性之外,我们还可以指定一些其他属性,如: sqlSessionFactory:这个属性已经废弃。当我们使用了多个数据源的时候我们就需要通过sqlSessionFactory来指定在注册MapperFactoryBean的时候需要使用的SqlSessionFactory, 因为在没有指定sqlSessionFactory的时候,会以Autowired的方式自动注入一个。换言之当我们只使用一个数据源的时候,即只定义了一个SqlSessionFactory的时候我们就可以不给 MapperScannerConfigurer指定SqlSessionFactory。 sqlSessionFactoryBeanName:它的功能跟sqlSessionFactory是一样的,只是它指定的是定义好的SqlSessionFactory对应的bean名称。 sqlSessionTemplate:这个属性已经废弃。它的功能也是相当于sqlSessionFactory的,因为就像前面说的那样,MapperFactoryBean最终还是使用的SqlSession的getMapper 方法取的对应的Mapper对象。当定义有多个SqlSessionTemplate的时候才需要指定它。对于一个MapperFactoryBean来说SqlSessionFactory和SqlSessionTemplate只需要其中一个就可以了, 当两者都指定了的时候,SqlSessionFactory会被忽略。 sqlSessionTemplateBeanName:指定需要使用的sqlSessionTemplate对应的bean名称。--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.test.app.dao"/> </bean> </beans>
5、ini.properties就不发了
6、generatorConfig.xml配置()
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration> <!-- !!!! Driver Class Path !!!! --> <classPathEntry location="E:\.m2\repository\com\microsoft\sqlserver\mssql-jdbc\6.2.0.jre8\mssql-jdbc-6.2.0.jre8.jar"/> <context id="context" targetRuntime="MyBatis3"> <commentGenerator> <property name="suppressAllComments" value="true"/> <property name="suppressDate" value="true"/> </commentGenerator> <!-- !!!! Database Configurations !!!! --> <jdbcConnection driverClass="${datasource.driver}" connectionURL="${datasource.url}" userId="${datasource.username}" password="${datasource.password}"/> <javaTypeResolver> <property name="forceBigDecimals" value="false"/> </javaTypeResolver> <!-- !!!! Model Configurations !!!! --> <javaModelGenerator targetPackage="com.hmc.crm.entity" targetProject="src\main\java"> <property name="enableSubPackages" value="false"/> <property name="trimStrings" value="true"/> </javaModelGenerator> <!-- !!!! Mapper XML Configurations !!!! --> <sqlMapGenerator targetPackage="com.hmc.crm.dao" targetProject="src\main\java\mapper"> <property name="enableSubPackages" value="false"/> </sqlMapGenerator> <!-- !!!! Mapper Interface Configurations !!!! --> <javaClientGenerator targetPackage="com.hmc.crm.dao" targetProject="src\main\java" type="XMLMAPPER"> <property name="enableSubPackages" value="false"/> </javaClientGenerator> <!-- !!!! Table Configurations !!!! --> <table tableName="UserType" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false"/> </context> </generatorConfiguration>
ps:在pom中配置过mybatis的generator插件 会自动读取 resources下的generatorConfig.xml 只需要双击插件即可如下图:
7、mybatis.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- Globally enables or disables any caches configured in any mapper under this configuration -->
<setting name="cacheEnabled" value="false"/>
<!-- Sets the number of seconds the driver will wait for a response from the database -->
<setting name="defaultStatementTimeout" value="3000"/>
<!-- Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names aColumn -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- Allows JDBC support for generated keys. A compatible driver is required.
This setting forces generated keys to be used if set to true,
as some drivers deny compatibility but still work -->
<setting name="useGeneratedKeys" value="true"/>
<setting name="logImpl" value="LOG4J2"/>
</settings>
<!-- Continue going here -->
</configuration>
8、log4j2.xml配置
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="off" monitorInterval="1800"> <properties> <property name="LOG_HOME">/logs/sample</property> <property name="FILE_NAME">mylog</property> </properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <RollingRandomAccessFile name="running-log" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd}-%i.log.gz"> <PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n"/> <Policies> <TimeBasedTriggeringPolicy/> <SizeBasedTriggeringPolicy size="10 MB"/> </Policies> <DefaultRolloverStrategy max="20"/> </RollingRandomAccessFile> </Appenders> <Loggers> <!--<Logger name="com.test.app" level="trace" additivity="true">--> <!--<AppenderRef ref="running-log"/>--> <!--</Logger>--> <Logger name="com.test.app.dao" level="DEBUG" additivity="true"> <AppenderRef ref="Console"/> </Logger> <Root level="error"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
ps: 在mybatis.xml中红色部分配置了日志实现方式。在log4j2中配置了dao层日志 为DEBUG且为 console 方式 方便调试时查看sql
接下来就是代码部分:
1、将generator生成的XXXXMapper.java拷贝到dao层下
2、新建HelloService.java和HelloServiceImpl.java 在service层下
public interface HelloService { public List<testModel> getAll(); } @Service public class HelloServiceImpl implements HelloService { @Autowired private XXXMapper dao; public List<testModel> getAllLabels() { return dao.selectAll(); }
}
3、新建HelloController.java 在controller层下
@Controller @RequestMapping("/hello") public class HelloController { @Autowired private HelloService service; @RequestMapping("/index.html") public String index(Model model) { model.addAttribute("title", "hello spring mvc"); model.addAttribute("model","正常显示"); return "index"; } @RequestMapping("/list.html") public String test(Model model, @RequestParam(defaultValue = "") String key) { List<testModel> ans=service.getAll(); model.addAttribute("all", ans); return "list"; } @RequestMapping("/list") @ResponseBody public List<testModel> list(){ List<testModel> ans=service.getAll(); return ans; }
}
4、在webapp/WEB-INF/view下新建list.ftl
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <tr> <th>名字</th> <th>年龄</th> </tr> <#list all as label> <tr> <td>${label.name}</td> <td>${label.age}</td> </tr> </#list> </table> </body> </html>
5.运行尝试
2017-7-16号更新 还是用spring boot 吧反正都帮你配好了 为什么不用呢 而且还可以打包成war 手动doge