SSM框架手动搭建

SSM框架手动搭建

创建web项目

IDEA创建Maven项目

[File]-->[new]-->[project..]

 

将项目变为web项目

[File]-->[Project Structure]-->[Modules]

路径:D:\dev\java-study\SSM\ssm-demo\src\main\webapp

配置war包

[File]-->[Project structure]--[Artifacts]

 

tomcat配置

[Run]-->[Edit Configurations]-->"+"

新建index.html文件

 <!doctype html>
 <html lang="en">
 <head><title>ssm-demo</title>
 
 </head>
 <body>
     <h3>hello world</h3>
 </body>
 </html>

spring

添加依赖包

 <properties>
     <spring.version>5.0.4.RELEASE</spring.version>
 </properties>
 
 <dependencies>
     <!--spring start-->
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-core</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-beans</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context-support</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-aop</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-aspects</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-expression</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-tx</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-test</artifactId>
         <version>${spring.version}</version>
     </dependency>
 
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-web</artifactId>
         <version>${spring.version}</version>
     </dependency>
     <!--spring end-->
 </dependencies>

自动生成xml文件

  1. 删除原有的spring文件

    [File]-->[Project Structure]-->[Moudules]

  2. 添加xml文件

    项目右键:

    选择spring mvc项

    自动生成以下3个文件

  3. 配置欢迎页

    引入jsp相关依赖(由于要用到jsp,所有要引入依赖)

     <properties>
         <javax.servlet.version>4.0.0</javax.servlet.version>
         <jstl.version>1.2</jstl.version>
     </properties>
     
     <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>javax.servlet-api</artifactId>
         <version>${javax.servlet.version}</version>
     </dependency>
     <dependency>
         <groupId>jstl</groupId>
         <artifactId>jstl</artifactId>
         <version>${jstl.version}</version>
     </dependency>

    web.xml

     <!--欢迎页-->
     <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
     </welcome-file-list>
  4. 新建index.jsp文件

     <%--
       Created by IntelliJ IDEA.
       User: Administrator
       Date: 2019/4/22 0022
       Time: 下午 18:04
       To change this template use File | Settings | File Templates.
     --%>
     <%@ page contentType="text/html;charset=UTF-8" language="java" %>
     <html>
     <head>
         <title>Title</title>
     </head>
     <body>
         <h1>hello spring mvc!</h1>
     </body>
     </html>
  5. 过程中遇到的错误

    Q:More than one fragment with the name [spring_web] was found

    A:这个问题是由于lib中引用了2个不同版本的“spring_web”包,检查下[File]-->[Project Structure]-->[Artifacts]中是否存在了重复,删除重复即可

项目架构

java结构

resource结构

在resource下新建config文件夹,然后新建spring文件夹,将applicationContext.xml和dispatcher-servlet.xml移入config.spring文件夹中,并将dispatcher-servlet.xml改名为spring-mvc.xml

spring-mvc

添加依赖包

 <properties>
     <spring.version>5.0.4.RELEASE</spring.version>
 </properties>
 
 <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-webmvc</artifactId>
     <version>${spring.version}</version>
 </dependency>

spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
        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">
 
     <!--扫描controller(后端控制器),并且扫描其中的注解-->
     <!--扫描base-package包或者子包下所有的controller类,并把匹配的controller类注册成Bean-->
     <context:component-scan base-package="com.ssm.controller"/>
 
     <!--启用spring注解-->
     <context:annotation-config/>
 
     <!--配置注解驱动:可以将request参数绑定到controller的参数上-->
     <!--该注解会自动注册RequestMappingHandlerMapping 和RequestMappingHandlerAdapter两个Bean,
         是Spring MVC为@Controller分发请求所必须的,
         并提供了数据绑定支持、@NumberFormatannotation支持、@DateTimeFormat支持、@Valid支持、读写XML的支持(JAXB)和读写JSON的支持(Jackson)等功能。-->
     <mvc:annotation-driven/>
 
     <!--jsp jstl-->
     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="prefix" value="/WEB-INF/views"/>
         <property name="suffix" value=".jsp"/>
     </bean>
 
     <!--配置视图解析器:对模型视图名称的解析-->
     <!--最常用的视图解析器,当控制层返回“hello”时,
         InternalResourceViewResolver解析器会自动添加前级和后缀,最终路径结果为:WEB-INF/views/hello.jsp-->
     <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
         <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
         <property name="prefix" value="/WEB-INF/views"/>
         <property name="suffix" value=".jsp"/>
         <property name="exposeContextBeansAsAttributes" value="true"/>
     </bean>
 
 </beans>

applicationContext.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"
        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">
 
     <!--启用注解扫描-->
     <!--:扫描base-package 包或者子包下所有的Java 类,并把匹配的Java类注册成Bean.这里我们设直扫描com.ssm包下的所有Java类-->
     <context:component-scan base-package="com.ssm">
         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
     </context:component-scan>
 </beans>

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_4_0.xsd"
         version="4.0">
    <!--组件加载-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:config/spring/applicationContext.xml</param-value>
    </context-param>

    <!--监听-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!--servlet-->
    <!--DispatcherServlet是前直控制器,主要用于拦截匹配的请求,
        拦截匹配规则要自己定义,把拦截下来的请求,依据相应的规则分发到目标Controller来
        处理,是配置SpringMVC的第一步-->
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--整个项目的局部变量, 相当于设定了一个固定值,只能在当前的Servlet中被使用
            param-name是键,相当于就是参数名,param-value是值,相当于参数值。
            容器启动时会加载配直文件spring-mvc.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:config/spring/spring-mvc.xml</param-value>
        </init-param>
        <!--表示启动容器时初始化该Servlet.
            当值为0或者大于0 时,表示容器在应用启动时力口载并初始化这个Servlet.
            如果值小于0或未指定时,则指示容器在该Servlet被选择时才加载.
            正值越小,Servlet的优先级越高,应用启动时就越先加载。值相同时,容器就会自己选择顺序来加载。-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--标签声明了与该Servlet相应的匹配规则,每个<url-pattern>标签代表1 个匹配规则。-->
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <!--URL 匹配规则,表示哪些请求交给Spring MVC处理,“/”表示拦截所有的请求(默认方式)。
            以“*.”开头的字符串被用于扩展名匹配,如*.do
            以“/”字符开头,并以“/*”结尾的字符串用于路径匹配,如:/test/*。
            当一个URL与多个Servlet 的匹配规则可以匹配时,则按照“精确路径>最长路径>扩展名” 这样的优先级匹配到对应的Servlet.-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--欢迎页-->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

编写controller

不传参

package com.ssm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

    @RequestMapping("index")
    public ModelAndView index(){
        return new ModelAndView("/hello");
    }

}

传参

package com.ssm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

    @RequestMapping("index")
    public ModelAndView index(){
        ModelMap modelMap = new ModelMap();
        modelMap.put("name","kinglead");
        return new ModelAndView("/hello",modelMap);
    }

}

mybatis

相关依赖

<properties>
    <spring.version>5.0.4.RELEASE</spring.version>
    <mysql.connector.java.version>8.0.9-rc</mysql.connector.java.version>
    <durid.version>1.1.9</durid.version>
    <mybatis.version>3.4.6</mybatis.version>
    <mybatis-spring.version>1.3.2</mybatis-spring.version>
</properties>

<!--mybatis start-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.connector.java.version}</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>${durid.version}</version>
</dependency>

<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>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${spring.version}</version>
</dependency>
<!--mybatis end-->

创建jdbc.properties文件

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm_demo?serverTimezone=GMT
jdbc.username=root
jdbc.password=123456

applicationContext加入读取properties文件配置

<!--加载properties配置文件-->
<!--<context:property-placeholder>:标签提供了一种优雅的外在化参数配直的方式,
        location表示属性文件位置,多个属性文件之间通过逗号分隔。ignore-unresolvable表示
        是否忽略解析不到的属性,如果不忽略,找不到将抛出异常。-->
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>

配置DataSource数据源

applicationContext加入:

<!--配置dataSource数据源:这里使用的是druid-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <!--连接池配置-->
    <!--最大并发连接数-->
    <!--初始化连接数量-->
    <!--最小空闲连接数-->
    <!--检测周期:检测需要关闭的空闲连接,单位用毫秒-->
</bean>

 

配置mybatis sqlSessionFactory

applicationContext加入:

<!--mybatis sqlSessionFactory-->
<!--在基本的MyBatis中,Session 工厂可以使用SqlSessionFactoryBuilder来创建。
        而在MyBatis-Spring中,则使用SqlSessionFactoryBean来替代。-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mapperLocations">
        <list>
            <value>classpath:com/ssm/mapper/*Mapper.xml</value>
        </list>
    </property>
</bean>
<!--<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--<constructor-arg index="0" ref="sqlSessionFactory"/>-->
<!--</bean>-->

<!--扫描basePackage下所有以@MyBatisDao注解的接口-->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <property name="basePackage" value="com.ssm.dao"/>
</bean>

mysql创建数据库,并创建表

(略)

IDEA中使用mybatis-generator自动生成mapper和pojo文件

https://blog.csdn.net/qq_38455201/article/details/79194792

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--namespace命名空间作用:对sql进行分类化管理,隔离
注意:使用mapper代理开发时,namespace将会有特殊重要的作用-->
<mapper namespace="com.ssm.dao.UserMapper">
    <!-- 在映射文件中配置很多sql语句 -->
    <!-- 将sql语句封装到mappedStatement对象中,所以将id称为statement的id -->
    <!-- parameterType:指定输入参数的类型,这里指定int型 #{}表示一个占位符号 -->
    <!-- #{id}:其中的id表示接收输入的参数,参数名称就是id,如果输入 -->
    <!-- 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称 -->
    <!-- resultType:指定sql输出结果的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。 -->
    <!-- 表名要对,但是不区分大小写,resultType要写类名,同样不区分大小写 -->
    <select id="findAll"  resultType="com.ssm.model.User">
        SELECT * FROM t_user
    </select>
</mapper>

具体java代码实现

创建model:User

package com.ssm.model;

public class User {

    private int id;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

DAO

package com.ssm.dao;

import com.ssm.model.User;
import java.util.List;

public interface UserMapper {

    List<User> findAll();

}

Service接口

package com.ssm.service;

import com.ssm.model.User;
import java.util.List;

public interface UserService {

    List<User> findAll();

}

Service接口实现

package com.ssm.service.impl;

import com.ssm.dao.UserMapper;
import com.ssm.model.User;
import com.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;


@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    public List<User> findAll() {
        return userMapper.findAll();
    }
}

Controller

package com.ssm.controller;

import com.ssm.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

    @Autowired
    UserService userService;

    @RequestMapping("index")
    public ModelAndView index(){
        ModelMap modelMap = new ModelMap();
        modelMap.put("name",userService.findAll().get(0).getName());
        return new ModelAndView("/hello",modelMap);
    }

}

问题:

  1. org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)

    一般的原因是Mapper interface和xml文件的定义对应不上,需要检查包名,namespace,函数名称等能否对应上,需要比较细致的对比,我经常就是写错了一两个字母搞的很长时间找不到错误

    按以下步骤一一执行:

    1:检查xml文件所在的package名称是否和interface对应的package名称一一对应

    2:检查xml文件的namespace是否和xml文件的package名称一一对应

    3:检查函数名称能否对应上

    4:去掉xml文件中的中文注释

    5:随意在xml文件中加一个空格或者空行然后保存

    一般来说到此就可以排除错误了。

    如果进行上述操作,问题还为解决,那就是编译时没有将*Mapper.xml编译,可在pom.xml文件中加入:

    <build>
        <resources>
            <!--将xml文件进行编译-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
    

集成log4j

Log句中有三个主要的组件,它们分别是: Logger (记录器)、Appender (输出端〉和Layout (布局) ,这三个组件可以简单地理解为日志类别,日志要输出的地方和日志以何种形式输 出。

  • Logger ( 记录器) : Logger组件被分为7个级别:“all、debug 、info 、warn 、error 、fatal 、 off。这7个级别是有优先级的: all <debug< info< warn< error< fatal<off,分别用来指定 这条日志信息的重要程度。Log4j有一个规则:只输出级别不低于设定级别的日志信 息。假设Logger级别设定为info ,则info 、warn 、error和fatal级别的日志信息都会输 出,而级别比info低的debug则不会输出。Log4j 允许开发人员定义多个Logger ,每个 Logger拥有自己的名字, Logger之间通过名字来表明隶属关系。

  • Appender C 输出端) : Log4j 日志系统允许把日志输出到不同的地方,如控制台 (Console )、文件( Files )等, 可以根据天数或者文件大小产生新的文件,可以以流 的形式发送到其他地方等等。

  • Layout ( 布局) : Layout的作用是控制log信息的输出方式,也就是格式化输出的信息。

添加依赖

<properties>
    <slf4j.version>1.7.7</slf4j.version>
    <log4j.version>1.2.17</log4j.version>
</properties>

<!--log4j start-->

<!--具体的日志系统。通过slf4j-log4j12初始化log4j,达到最终日志的输出。-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>${log4j.version}</version>
</dependency>

<!--slf4j-api:全称Simple Logging Facade For Java ,为Java提供的简单日志Facade。Facade
            门面就是接口,它允许用户以自己的喜好,在项目中通过时slf4j接入不同的日志系统。
            更直观一点,slf4j是个数据线,一端嵌入程序,另一端链接日志系统,从而实现将程
            序中的信息导入到日志系统并记录。-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>

<!--链接slf4j-api和log4j的适配器-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<!--log4j end-->

格式配置文件

###set log levels
log4j.rootLogger = DEBUG,Console

###print console
log4j.appender.Console = org.apache.log4j.ConsoleAppender
log4j.appender.Console.Target = System.out
log4j.appender.Console.layout = org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n

集成Junit测试框架

添加依赖

<!--junit:单元测试框架-->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

建立测试类

路径:src/test/java/com/ssm/test

package com.ssm.test;

import com.ssm.dao.UserMapper;
import com.ssm.model.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;

/**
 @RunWith :参数化运行器,用于指定Junit运行环境,是Junit提供给其他框架测试环境接口扩展,
            为了便于使用Spring的依赖注入,Spring提供了SpringJUnit4ClassRunner作为JUnit测试环境。
 @ContextConfiguration :加载配直文件applicationContext.xml
 **/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/config/spring/applicationContext.xml"})
public class UserTest {

    @Resource
    private UserMapper userMapper;

    @Test
    public void testUser(){
        List<User> userList = userMapper.findAll();
        System.out.println("userList:"+userList.get(0).getName());
    }

}

 

——————————————以上已完成框架搭建————————————————

 

spring mvc相关知识

基本注解

Spring 提供的注解有很多,比如声明Bean 的注解和注入Bean 的注解, 这些注解在工作中 经常被使用。

声明Bean 的注解:

• @Component 没有明确的角色。 • @Service 在服务层( 业务逻辑层)被使用。 • @Repository 在数据访问层( dao层) 被使用。 • @Controller 在表现层(控制层)被使用。

注入Bean 的注解:

• @Autowired Sprin g提供的注解。 • @Resource JSR-250提供的注解。

注意, @Resource 这个注解属于J2EE 的, 默认安照名称进行装配,名称可以通过name 属 性进行指定。如果没有指定name 属性,当注解写在字段上时,默认取字段名进行查找。如果 注解写在seter 方法上默认取属性名进行装配。当找不到与名称匹配的bean 时才按照类型进行 装配。但是需要注意的是,如果name 属性一旦指定,就只会按照名称进行装配。具体代码 如下:

@Resource(name="ayUserDao")
private AyUserDao ayUserDao;

而@Autowired 这个注解是属于Spring 的, 默认按类型装配。默认情况下要求依赖对象必须存 在,如果要允许null 值,可以设置它的required 属性为false ,如: @Autowired(required=false),如 果我们想使用名称装配,可以结合@Qualifier 注解进行使用。具体代码如下:

@Autowired
@Qualifier("ayUserDao")
private AyUserDao ayUserDao;

 

集成Redis缓存

添加依赖

在SSM 框架中集成Redis 缓存, 首先需要在pom.xml 文件中引入所需的依赖, 具体代码 如下:

配置

在pom 文件引入Redis 所需的依赖之后,还需要在src\main\resources 目录下创建 redis .properties 文件并添加如下的配置信息:

在src\main\resources 目录下创建spring-redis.xml 配置文件并添加如下配置信息:

在src\main\resources\applicationContext.xml 配置文件中导入spring-redis.xml 配置, 具体代 码如下:

测试类

所有的配置文件添加完成后, 在src\main\test\com\ay\test 目录下创建测试类 RedisTest.java,具体代码如下:

RedisTemplate 和StringRedisTemplate 都是Spring Data Redis 为我们提供的两个模板类用来 对数据进行操作,其中StringRedisTemplate 只针对键值都是字符串的数据进行操作。在应用启 动的时候, Spring 会初始化这两个模板类,通过@Resource 注解注入即可使用。 RedisTemplate和StringRedisTemplate 除了提供opsForValue 方法用来操作简单属性数据之 外,还提供了以下其他主要数据的访问方法:

当数据存放到Redis 的时候,键( key )和值( va lu e )都是通过Spring 提供的Serializer 序 列化到数据库的。RedisTemplate 默认使用JdkSeri al izationRedisSerializer , 而 StringRedi sTemplate 默认使用StringRedisSerializer 。

RedisTest 开发完成后,运行测试类RedisTest 的testRedis ()方法,找到Red is 客户端程序redis - cli. exe ,当在客户端输入命令: “ get name ” 后可以获取到值,同时可以在IDEA 控制台中看到打印的信息,表示SSM 框架成功地集成了Red i s 缓存。

集成ActiveMQ

添加依赖

在SSM 框架中集成ActiveMQ 缓存, 首先需要在pom.xml 文件中寻|入所需的依赖,具体代码如下:

配置

依赖添加完成之后,需要在\src\main\resources 目录下创建Active MQ 配置文件 spring-jms.xml , 具体代码如下:

在配置文件spring-jms.xml 中, 首先定义了ActiveMQ 的连接信息, 然后定义了 JmsTemplate 工具类, 该工具类是Spring 框架提供的, 利用JmsTemplate 可以很方便地发送和接 收消息。最后, 我们定义消费者类moodConsumer ,同时消费者监听的是 ay .queue.high.concurrency .praise 这个topic,当有生产者Producer 往该队列推送消息时- , 消费者 Consumer 就可以监听到该消息, 井做相应的逻辑处理。

在\src\main\resources 目录下创建配置文件activemq.properties, 具体代码如下:

activemq.prope此ies 属性文件主要配置ActiveMQ 的连接信息,供spring-jms.xml 配置文件使用。 spring-jms.xml 开发完成之后, 在applicationContext.xml 配置文件中使用<import>标签引入 入spring-jms. xml 配置文件, 具体代码如下:

异步消费

上一节,已经在项目中集成了ActiveMQ 消息中间件,同时开发了相关的配置文件,这一 节主要利用ActiveMQ 实现点赞功能的异步处理。具体步骤如下:

首先,在src\main\java\com\ay\mq 目录下创建生产者类MoodProducer , 具体代码如下:

MoodProducer 类提供sendMessage 方法用来发送消息,方法的第一个参数是destination , 主 要用来指定队列的名称,第二个参数是mood 说说实体。通过调用jmsTemplate 工具类的 convertAndSend 方法发送消息。需要注意的是, MoodDTO 说说实体需要实现序列化接口 Serializable , 具体代码如下:

其次,在src\main\java\com\ay\mq 目录下创建消费者类MoodConsumer 。

消费者类MoodConsumer 实现MessageListener 接口,完成对消息的监昕和接收。消息有两 种接收方式: 同步接收和异步接收。

• 同步接收: 主线程阻塞式等待下一个消息的到来, 可以设置timeout,超时则返回null 。 • 异步接收: 主线程设置MessageListener , 然后继续做自己的事, 子线程负责监听。

同步接收又称为阻塞式接收, 异步接收又称为事件驱动的接收。同步接收,是在获取 MessageConsumer 实例之后, 调用以下的API:

• receive() 获取下一个消息。该调用将导致无限期的阻塞, 直到有新的消息产生。 • receive(long timeout) 获取下一个消息。该调用可能导致一段时间的阻塞, 直到超时 或者有新的消息产生。超时则返回null 。 • receiveNoWait() 获取下一个消息。这个调用不会导致阻塞, 如果没有下一个消息, 直接返回null .

异步接收, 是在获取MessageConsumer 实例之后, 调用下面的API : • setMessagelistener(Messagelistener) 设置消息监听器。MessageListener是一个接 口,只定义了一个方法,即。由onMessage(Message message)回调方法, 当有新的消息产生 时,该方法会被自动调用。

可见, 为实现异步接收, 只需要对MessageListener 进行实现,然后设置为Consumer 实例 的messageListener 即可。

最后,修改MoodServivelmpl 类中的praiseMoodForRedis()方法,将其改成异步处理方式, 具体代码如下:

 

posted on 2019-06-05 11:49  kinglead  阅读(693)  评论(1编辑  收藏  举报

导航