spring整合框架的方式分为xml配置文件和java配置两种方式,这里介绍的是以java配置的方式。整合思路大致如下:首先通过配置文件配置视图解析器,并开启针对controller的自动扫描,将controller装配到容器中,完成以上配置后,接下来是针对数据库后端操作进行整合,选择适当的数据库连接池对数据源进行相关配置,配置成功以后,再针对sqlSessionFactory进行整合,配置完成后,开启针对service、dao的自动扫描,以及mybatis针对dao的扫描,并确保mapper.xml文件已经被编译到项目中(一般java项目在进行编译的时候是不会编译xml文件的,需要在pom文件中添加对mapper的编译)。以下是maven需要导入的jar包。
org.freemarker
freemarker
2.3.28
javax.servlet
javax.servlet-api
3.1.0
provided
org.springframework
spring-aop
4.3.10.RELEASE
org.springframework
spring-aspects
4.3.10.RELEASE
org.springframework
spring-context-support
4.3.10.RELEASE
org.springframework
spring-jdbc
4.3.10.RELEASE
org.springframework
spring-tx
4.3.10.RELEASE
org.springframework
spring-web
4.3.10.RELEASE
org.springframework
spring-webmvc
4.3.10.RELEASE
org.springframework
spring-webmvc-portlet
4.3.10.RELEASE
org.mybatis
mybatis
3.2.8
org.mybatis
mybatis-spring
1.2.0
mysql
mysql-connector-java
5.1.38
jstl
jstl
1.2
commons-collections
commons-collections
3.2
org.aspectj
aspectjweaver
1.6.9
aopalliance
aopalliance
1.0
cglib
cglib-nodep
2.2
com.mchange
c3p0
0.9.5.2
commons-fileupload
commons-fileupload
1.3.3
log4j
log4j
1.2.15
runtime
com.github.pagehelper
pagehelper
4.1.6
com.alibaba
fastjson
1.2.12
com.fasterxml.jackson.core
jackson-core
2.5.0
com.fasterxml.jackson.core
jackson-annotations
2.5.0
com.fasterxml.jackson.core
jackson-databind
2.5.0
首先是spring和mvc的整合,需要创建一个配置类继承 AbstractAnnotationConfigDispatcherServletInitializer 这个类,这个类相当于整个Web项目的配置文件(web.xml),他会包含一些其他的子配置文件。以下三个方法是必须需要实现的,第一个getRootConfigClasses方法,该方法会去加载RootConfig这个配置类(这个类相当于applicationContext)。第二个getServletConfigClasses方法,该方法会去加载WebConfig这个配置类(这个类相当于mvc的配置文件)。第三个getServletMappings方法,通过这个方法来配置该项目的请求方式。代码如下:
package config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
/**
* @Description
* @auther Mr.DayDream
* @create 2019-02-13 16:05
* @deprecated web项目的初始文件,有了它就不用再单独实现WebApplicationInitializer接口了,因为他已经实现了,只要是实现了这个的类都可以用来代替web.xml
*/
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
*
* 设置application的配置类
*
* */
protected Class>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
/**
*
* 设置mvc的配置类
*
* */
protected Class>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
/**
*
* 配置项目默认请求路径,用来映射dispatcherServlet
*
* */
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
*
* 给dispatcherServlet添加过滤器
*
* */
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter=new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
return new Filter[]{filter};
}
/**
*
* 通过这个方法可以单独添加servlet、listener、filter
*
* */
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
}
}
然后再创建RootConfig和WebConfig这两个配置文件。先来介绍WebConfig这个文件,创建WebConfig这个类需要去继承WebMvcConfigurerAdapter这个类。给这个类添加上@Configuration注解,表明这个类是一个配置类。再添加@EnableWebMvc注解,表明这个类是mvc的配置类(这两个注解是必填的)。再然后是@ComponentScan注解,通过这个注解指定的范围针对标注了@controller的java类进行扫描并装配到bean容器中。在这个类中配置视图解析器、静态资源访问、文件上传等。
package config;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import java.io.IOException;
/**
* @Description
* @auther Mr.DayDream
* @create 2019-02-13 16:12
* @deprecated 相当于xml方式的mvc配置文件
*/
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "controller")
public class WebConfig extends WebMvcConfigurerAdapter {
/**
*
* 配置jsp视图解析器
*
* */
@Bean
public ViewResolver internalResourceViewResolver(){
InternalResourceViewResolver resolver=new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setOrder(1);
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
/**
*
* 将freemarker.properties装载进来
*
* */
@Bean
public PropertiesFactoryBean propertiesFactoryBean(){
PropertiesFactoryBean propertiesFactoryBean=new PropertiesFactoryBean();
propertiesFactoryBean.setLocations(new PathMatchingResourcePatternResolver().getResource("classpath:freeMarkerConfig.properties"));
return propertiesFactoryBean;
}
/**
*
* 初始化FreeMarker模板
*
* */
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer(PropertiesFactoryBean propertiesFactoryBean) throws IOException {
FreeMarkerConfigurer freeMarkerConfigurer=new FreeMarkerConfigurer();
freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/");
freeMarkerConfigurer.setFreemarkerSettings(propertiesFactoryBean.getObject());
return freeMarkerConfigurer;
}
/**
*
* 配置FreeMarker视图解析器
*
* */
@Bean
public ViewResolver freeMarkerViewResolver(){
FreeMarkerViewResolver freeMarkerViewResolver=new FreeMarkerViewResolver();
freeMarkerViewResolver.setExposeRequestAttributes(true);
freeMarkerViewResolver.setExposeSessionAttributes(true);
freeMarkerViewResolver.setViewClass(FreeMarkerView.class);
freeMarkerViewResolver.setSuffix(".html");
freeMarkerViewResolver.setOrder(0);
return freeMarkerViewResolver;
}
/**
*
* 配置静态资源的访问(这样配置以后,就可以访问到WEB-INF下的静态资源)
*
* */
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resource/**").addResourceLocations("/WEB-INF/static/");
}
/**
*
* 配置静态资源的访问(配置这个以后,可以直接访问web根目录下的静态资源[也就是webapp下的静态资源])
*
* */
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
/**
*
* 设置项目默认访问页面
*
* */
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
/**
*
* 配置上传文件
* */
@Bean
public MultipartResolver multipartResolver(){
CommonsMultipartResolver multipartResolver=new CommonsMultipartResolver();
multipartResolver.setDefaultEncoding("UTF-8");
return multipartResolver;
}
}
接下来是RootConfig文件,首先需要添加的是@Configuration注解来表明这个类是一个配置类,因为这个类相当于application这个xml配置文件,所以需要在该类上@ComponentScan注解,用来扫描service、dao。因为需要对mybatis的mapper进行整合,还需要添加@MapperScan注解。@EnableAspectJAutoProxy这个注解是用来标识下面配置的切面的,在这个配置类中需要对数据源、sqlSessionFactory、分页插件进行配置。
import aop.TestAop;
import com.github.pagehelper.PageHelper;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.io.IOException;
import java.util.Properties;
/**
* @Description
* @auther Mr.DayDream
* @create 2019-02-13 16:47
* @deprecated 相当于xml方式的application文件
*/
@Configuration
@ComponentScan(basePackages = {"service.impl","dao"})
@MapperScan(basePackages = "dao")
@EnableAspectJAutoProxy
public class RootConfig {
/**
*
* 配置数据源,spring装载properties可以通过PropertiesFactoryBean【PropertiesFactoryBean主要用来装配单例的Properties】,也可以通过PropertiesLoaderUtils工具类
*
* */
@Bean
public DataSource dataSource() throws IOException, PropertyVetoException {
ComboPooledDataSource dataSource=new ComboPooledDataSource();
Properties properties=PropertiesLoaderUtils.loadProperties(new PathMatchingResourcePatternResolver().getResource("classpath:jdbc.properties"));
dataSource.setDriverClass(properties.getProperty("jdbc.driver"));
dataSource.setJdbcUrl(properties.getProperty("jdbc.url"));
dataSource.setUser(properties.getProperty("jdbc.username"));
dataSource.setPassword(properties.getProperty("jdbc.password"));
dataSource.setInitialPoolSize(Integer.parseInt(properties.getProperty("jdbc.initialPoolSize")));
dataSource.setMinPoolSize(Integer.parseInt(properties.getProperty("jdbc.minPoolSize")));
dataSource.setMinPoolSize(Integer.parseInt(properties.getProperty("jdbc.maxPoolSize")));
return dataSource;
}
/**
*
* 整合sqlSessionFactory
*
* */
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource,PageHelper pageHelper) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*Mapper.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("entity");
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
return sqlSessionFactoryBean.getObject();
}
/**
*
* 配置分页插件
*
* */
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper=new PageHelper();
Properties properties= new Properties();
properties.setProperty("helperDialect","true");
properties.setProperty("reasonable","true");
properties.setProperty("autoRuntimeDialect","true");
pageHelper.setProperties(properties);
return pageHelper;
}
@Bean
public TestAop testAop(){
return new TestAop();
}
}
回来RootConfig中的测试aop,示例代码如下:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
/**
* @Description
* @auther Mr.DayDream
* @create 2019-02-13 21:56
* @deprecated
*/
@Aspect //通过这个注解表明这个类是一个自定义的切面类。
public class TestAop {
//这里是这个切面要切的方法,也就是切点
@Pointcut("execution(* service.impl.PersonServiceImpl.findAll())")
public void findAll(){
}
//这里是针对findAll方法做的环绕通知,如果切点有返回值,返回类型就为Object,否则是void
@Around("findAll()")
public Object huanraoAop(ProceedingJoinPoint proceedingJoinPoint){
Object o=null;
System.out.println("查询之前");
try {
o= proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("查询之后");
return o;
}
}
在这里列出上面用到的两个properties(分别是freeMarker模板配置和数据库连接):
template_update_delay=0
default_encoding=UTF-8
number_format=0.##########
datetime_format=yyyy-MM-dd HH:mm:ss
classic_compatible=true
template_exception_handler=ignore
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/learn?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
jdbc.initialPoolSize=10
jdbc.minPoolSize=10
jdbc.maxPoolSize=100
到这里,还需要对mapper的xml文件做一下重构,因为是maven创建的项目,部署到tomcat后,xml并不会被编译,这会导致mybatis的异常,要解决这个问题只需在pom的build标签下添加如下代码:
src/main/java
mapper/*.xml
这样,SSM就算是整合成功了,项目地址。https://github.com/13944487443/SSM.git