创建项目
长期以来,我都使用IDEA开发项目,所以教程是基于IDEA的操作来说的。
- 首先,在IDEA中建立一个Web Application的项目。
毫无疑问这里的两个前提是,你需要有JDK,并且在本地配置了Tomcat,才能继续。
- 当建立完成项目之后,IDEA会自动做一些生成操作,包括了一个基础的java web代码结构。
- 接下来需要在其中引入需要的Spring的maven依赖。右击左上角的项目名称,点击
Add Framework Support
,在其中选择Maven
并确认。
当Maven初始化完成,就可以开始添加依赖了,依赖包括了maven的编译插件以及Spring依赖和第三方常用依赖。
下面是我配置的Maven常用代码段,spring的版本是4.3.7.RELEASE,你可以在
标签内替换成其他版本即可。
4.3.7.RELEASE
jdk-1.8
true
1.8
1.8
1.8
1.8
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet
jstl
1.2
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-oxm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-core
4.3.7.RELEASE
org.springframework.data
spring-data-commons
1.13.1.RELEASE
org.springframework.data
spring-data-jpa
1.11.3.RELEASE
junit
junit
4.12
com.mchange
c3p0
0.9.5.2
mysql
mysql-connector-java
6.0.5
org.hibernate
hibernate-core
5.2.8.Final
org.apache.logging.log4j
log4j-core
2.8.1
org.apache.logging.log4j
log4j-api
2.8.1
org.apache.logging.log4j
log4j-slf4j-impl
2.8.1
com.alibaba
fastjson
1.2.31
org.apache.commons
commons-lang3
3.4
org.apache.commons
commons-collections4
4.1
commons-dbutils
commons-dbutils
1.6
等待所有的依赖进度加载完成,就可以开始配置Spring了。
Maven的速度可能会非常慢,需要的话自行百度阿里镜像。
配置基础的结构
在Spring的官方文档和实例中,有一种抽象类叫做AbstractAnnotationConfigDispatcherServletInitializer
这是用来配置web应用的初始化类,会在Spring web应用启动时先于用户配置被加载。其中提供了三个与Web应用配置有关的抽象方法,getRootConfigClasses
,getServletConfigClasses
,getServletMappings
。
这三个方法作用分别是:
- getRootConfigClasses: 返回根上下文配置的类
- getServletConfigClasses: 返回配置了web上下文的类
- getServletMappings: 返回根ServletMapping的路径
所以在配置开始的时候,需要手写一个启动类继承AbstractAnnotationConfigDispatcherServletInitializer
抽象类,并实现上述三个方法。这样在系统启动的时候,会自动加载指定的方法。
一般情况下,我使用一个RootConfiguration
类表示根上下文,使用一个ServletConfiguration
类表示web上下文。
编写启动类Bootstrap
类如下:
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* Created by HMH on 2017/9/25.
*/
public class Bootstrap extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class>[] getRootConfigClasses() {
return new Class>[] { RootConfiguration.class };
}
protected Class>[] getServletConfigClasses() {
return new Class>[] { ServletConfiguration.class };
}
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
在getRootConfigClasses方法中,你可以返回各种配置信息,包括配置数据库的类、配置安全的类、配置消息的类等等。
配置ServletConfiguration
在ServletConfiguration
类中,这里只做一个简单的例子,配置一个jsp解析的前后缀,这是为了返回页面的时候,不需要写千篇一律的前后缀,在该类中可以定义Json解析、内容协商等等一系列的配置项。几乎和请求、解析、返回等Servlet相关的内容都配置在这里。
@Configuration
//@ImportResource("classpath:dispatcher-servlet.xml")
@EnableWebMvc
@ComponentScan(
basePackages = "cn.hhchat.configDemo",
includeFilters = {
@ComponentScan.Filter(Controller.class),
@ComponentScan.Filter(ControllerAdvice.class)
})
public class ServletConfiguration extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
registry.viewResolver(viewResolver);
}
}
其中,
@Configuration
表示这是一个配置类;
@EnableWebMvc
可以屏蔽@EnableAutoConfiguration
,一般与WebMvcConfigurerAdapter
联用;
@ComponentScan
是自动装配的核心,其中定义了搜索的包路径,以及搜索的目标注解。
WebMvcConfigurerAdapter
也是一个抽象类,实现了一些操作,允许用户重写或实现其中一些方法来定制Servlet。
这里只实现了configureViewResolvers
,在mvc方法返回String
的时候自动添加前后缀。
配置RootConfiguration / Spring Data
RootConfiguration
中可以配置全局都用得到的一些配置,在平时练习的时候,我就直接在这里配置Spring Data。
Spring Data和Hibernate / Mybatis的比较这里不在意,所以直接讲配置的情况。这里的配置,我曾经卡了一个月的时间,在网上找了非常的多的资料 - - 他们都是抄的前篇一律。。。最终还是靠官方文档来解决。。。
这里需要配置3个部分,分别是:
- dataSource数据源
- entityManagerFactory实体工厂
- transactionManager事务管理器
其实这里的配置非常直接,对于hibernate也是这么配置的(毕竟spring data jpa 是对hibernate的封装。。),但我之前就卡在不知道使用什么实现类来配置这些内容。
@Configuration
@EnableJpaRepositories(basePackages = "cn.hhchat.configDemo")
@ComponentScan(basePackages = "cn.hhchat.configDemo",excludeFilters = {
@ComponentScan.Filter(EnableWebMvc.class), @ComponentScan.Filter(Controller.class)
})
public class RootConfiguration {
/**
* 配置数据源
*/
@Bean
public DataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://**host**/**database**?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false");
dataSource.setUser("**user**");
dataSource.setPassword("**pass**");
dataSource.setMinPoolSize(1);
dataSource.setMaxPoolSize(30);
dataSource.setInitialPoolSize(5);
dataSource.setAcquireIncrement(2);
return dataSource;
}
/**
* 配置实体工厂
*/
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
Properties properties = new Properties();
properties.put("hibernate.format_sql", "true");
properties.put("hibernate.show_sql", "true");
properties.put("hibernate.hbm2ddl.auto", "update");
properties.put("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
entityManagerFactoryBean.setJpaProperties(properties);
entityManagerFactoryBean.setPackagesToScan("org.example.site");
return entityManagerFactoryBean;
}
/**
* 配置事务
*/
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
jpaTransactionManager.setEntityManagerFactory(entityManagerFactory);
return jpaTransactionManager;
}
}
整个类的配置如上所示,挪用的话,需要修改数据库连接的地址、用户名、密码、和扫描的包。
需要注意的地方是在配置ServletConfiguration/RootConfigurationComponentScan的时候,一定要定义的非常细致。
对于Servlet来说只要Controller相关的注解,而root要剔除Controller。
对于Repository来说要直接指定到包含Entity注解和Repository注解的包中,这样能够避免搜索过程可能被屏蔽。这个地方曾经坑了我两天。。
尝试启动
编写一些代码,在IDEA中将所有的依赖添加到lib文件夹中,保证运行时可以被获取到。
启动你的项目,测试一下吧。