在上一篇文章中介紹了使用注解和xml配置文件對項目進行配置,在這篇文章中將xml配置文件中的配置信息都改成使用注解或者配置類的形式。
基於注解和xml配置的SSM(Spring+SpringMVC+Mybatis)項目詳細配置
第一步、配置pom.xml
在一個ssm項目中,可能需要用到的依賴比較多,在這里先列舉出來:

<!-- 屬性配置 --> <properties> <!-- 設置項目的編碼 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 設置java的版本為1.8--> <java.version>1.8</java.version> <!-- 源碼編譯的版本為1.8--> <maven.compiler.source>1.8</maven.compiler.source> <!-- 目標字節碼的版本為1.8--> <maven.compiler.target>1.8</maven.compiler.target> <!-- 指定編譯器版本為1.8--> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> <!-- 依賴的版本號 --> <spring.version>5.1.5.RELEASE</spring.version> <junit.version>4.12</junit.version> <mysql.version>5.1.47</mysql.version> <mybatis.version>3.5.2</mybatis.version> <mybatis.spring.version>2.0.3</mybatis.spring.version> <druid.version>1.1.20</druid.version> <project.version>1.0-SNAPSHOT</project.version> <servlet.version>4.0.1</servlet.version> <jackson.version>2.10.0</jackson.version> <pagehelper.version>5.1.10</pagehelper.version> <logback.version>1.2.3</logback.version> </properties> <!-- 添加依賴 --> <dependencyManagement> <dependencies> <!-- 測試 --> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- mysql驅動 --> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <!-- spring --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-context --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- spring mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- spring jdbc --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!-- druid連接池 --> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- 事務管理 --> <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.1.5.RELEASE</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>${mybatis.version}</version> </dependency> <!-- mybatis整合插件 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>${mybatis.spring.version}</version> </dependency> <!-- Jackson --> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> <!-- servlet --> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <!-- 分頁插件 --> <!-- pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>${pagehelper.version}</version> </dependency> <!-- 日志框架 --> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>${logback.version}</version> </dependency> <!-- 日志 --> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> </dependencies> </dependencyManagement>
第二步、dao層配置
在dao層中,主要就是配置連接池,mybatis和分頁插件
1、創建包:
創建如下:
DaoConfig.java:在這里配置了數據源和SqlSessionFactoryBean。
/** * 標識當前類是配置類 */ @Configuration /** * 等同於配置文件中<mybatis:scan/> */ @MapperScan("edu.nf.clazz.dao") public class DaoConfig { /** * 配置 * @return * @throws SQLException */ @Bean(initMethod = "init", destroyMethod = "close") public DataSource dataSource() throws SQLException { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName("com.mysql.jdbc.Driver"); ds.setUrl("jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&encoding=utf-8"); ds.setUsername("root"); ds.setPassword("root"); ds.setFilters("stat"); ds.setInitialSize(5); ds.setMaxActive(200); ds.setMinIdle(5); ds.setMaxWait(60000); ds.setMinEvictableIdleTimeMillis(300000); ds.setTimeBetweenEvictionRunsMillis(60000); ds.setTestWhileIdle(true); ds.setTestOnBorrow(false); ds.setPoolPreparedStatements(false); ds.setTestOnReturn(false); ds.setValidationQuery("select 1"); return ds; } @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); //注入數據源 factoryBean.setDataSource(dataSource); //設置實體包的別名 factoryBean.setTypeAliasesPackage("edu.nf.ch06.entity"); //指定mapper映射文件的路徑 PathMatchingResourcePatternResolver resource = new PathMatchingResourcePatternResolver(); factoryBean.setMapperLocations(resource.getResource("classpath:mapper/CityMapper.xml")); //配置分頁插件 PageInterceptor pageInterceptor = new PageInterceptor(); Properties props = new Properties(); props.setProperty("helperDialect", "mysql"); props.setProperty("supportMethodsArguments", "true"); props.setProperty("rowBoundsWithCount", "true"); pageInterceptor.setProperties(props); factoryBean.setPlugins(pageInterceptor); return factoryBean; } }
對於CityDao.java,City.java兩個類和CityMapper.xml映射文件與上一篇基於配置文件的內容一致,可以查閱上一篇文章。
第三步、service層配置
1、創建包:
可以看到,使用配置類配置的話,就可以不再使用xml配置文件,可以在ServiceConfig.java類中配置,其他的包結構都不變。
ServiceConfig.java:在這個配置類中主要配置了事務管理和啟用了AdpectJ注解處理器。
@Configuration @ComponentScan("edu.nf.clazz.service") @Import(DaoConfig.class) /** * 開啟事務注解,等同於配置文件<tx:annotation-driven/> */ @EnableTransactionManagement /** * 啟用AspectJ注解處理器,等同於xml中的<aop:aspectj-autoproxy/> * 面向切面編程 */ @EnableAspectJAutoProxy public class ServiceConfig { /** * 配置事務管理,並注入數據源 * @return * @throws SQLException */ @Bean public PlatformTransactionManager txManager(DataSource dataSource) throws SQLException { return new DataSourceTransactionManager(dataSource); } }
在這里,CityService.java、CityServiceImpl.java、DataAccessExcetption.java三個類都不變,除了CityAspect.java類我使用了另一種配置,在上面的ServiceConfig.java配置類中配置了@EnableAspectJAutoProxy注解,所以在CityAspect.java中就用注解的方式配置切面通知。(spring-study ch14-ch15)
AbstractAspect.java:
public class AbstractAspect { /** *聲明一個切入點,@Pointcut標注在方法上 * execution(訪問修飾符 方法返回值 包名.類名.方法名(參數類型)) * execution是切入到方法級別的 */ @Pointcut("execution(* edu.nf.clazz.service.impl.CityServiceImpl.*(..))") protected void pointcut(){ } }
CityAspect.java:
@Component /** * @Aspect:標識當前類是切面類。 */ @Aspect public class CityAspect extends AbstractAspect { /** * 前置通知 * @param jp 連接點,通過這個連接點可以獲取目標方法。 * pointcut()指的是切入點注解所標注的方法名 * 想用不同的通知可以使用不同的切入點 * 如:@Before("execution(* edu.nf.clazz.service.impl.CityServiceImpl.getCity(..))") */ @Before("pointcut()") public void before(JoinPoint jp){ System.out.println("前置通知,目標方法參數:" + jp.getArgs()[0]); } /** * 環繞通知 * @param pjp * @return * @throws Throwable */ @Around("pointcut()") public Object around(ProceedingJoinPoint pjp) throws Throwable{ System.out.println("環繞通知前..."); //獲取目標方法的Method對象 MethodSignature ms = (MethodSignature) pjp.getSignature(); Method method = ms.getMethod(); System.out.println("當前調用的目標方法:" + method.getName()); //調用目標方法 Object returnVal = pjp.proceed(); System.out.println("環繞通知后..."); return returnVal; } /** * 后置通知 * @param returnVal 目標對象的返回值 */ @AfterReturning(value = "pointcut()", returning = "returnVal") public void afterReturning(String returnVal){ System.out.println("后置通知,返回參數:" + returnVal); } /** * 異常通知 * @param e 目標方法產生的異常信息 */ public void afterThrowing(Throwable e){ System.out.println("異常通知:異常信息:" + e.getMessage()); } /** * 最終通知 */ @After("pointcut()") public void after(){ System.out.println("最終通知..."); } }
第四步、controller層配置
1、創建包:
MvcConfig.java:這個配置類主要配置了視圖解析器和靜態資源處理器
@Configuration /** * 掃描controller包 */ @ComponentScan(basePackages = "edu.nf.clazz.controller") /** * 啟用mvc注解處理驅動, * 等同於配置文件中的<mvc:annotation-driver/> */ @EnableWebMvc public class MvcConfig implements WebMvcConfigurer { /** * 啟用默認servlet處理靜態資源 * @param configurer */ @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } /** * 配置內部資源試圖解析器 * @return */ @Bean public InternalResourceViewResolver viewResolver(){ InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
WebInit.java:這個配置類相對於取代了web.xml配置文件,在這里可以指定父子容器的配置類、DispatcherServlet的請求映射url和動態注冊Filter,這里注冊了字符編碼過濾器
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer { /** * 指定DaoConfig.class配置類,也就是父容器的配置類 * @return */ @Override protected Class<?>[] getRootConfigClasses() { return new Class[]{ServiceConfig.class}; } /** * 指定spring mvc的配置類(MvcConfig.class),也就是子容器的配置類 * @return */ @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{MvcConfig.class}; } /** *指定DispatcherServlet的請求映射url * @return */ @Override protected String[] getServletMappings() { return new String[]{"/"}; } /** * onStartup中動態注冊字符過濾器 * @param servletContext * @throws ServletException */ @Override public void onStartup(ServletContext servletContext) throws ServletException { //配置字符過濾器 FilterRegistration.Dynamic encodingFilter = servletContext.addFilter("encodingFilter", new CharacterEncodingFilter()); encodingFilter.setInitParameter("encoding", "utf-8"); encodingFilter.setInitParameter("forceEncoding", "true"); encodingFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), false, "/*"); super.onStartup(servletContext); } }