基於注解和配置類的SSM(Spring+SpringMVC+Mybatis)項目詳細配置


在上一篇文章中介紹了使用注解和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、創建包:

創建如下:

 

可以看到,除了CityMapper.xml映射文件,在resource目錄中已經不存在xml配置文件了,而dao層相關的配置都在config包下的DaoConfig.java類中

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&amp;useUnicode=true&amp;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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM