Java微服务_SpringBoot服务整合

67 篇文章 0 订阅
SpringBoot服务整合
 
本小记学习目标
  1. 整合数据源
  2. 整合ORM开发框架
  3. 整合消息服务组件
  4. 整合Redis数据库
 
SpringBoot开发框架可以极大地简化第三方框架及第三方服务之间的整合处理。
 
一、SpringBoot整合数据源
实际的项目开发中,一般来说都会使用到数据库,为了提高数据库的操作性能,开发的过程中通常会使用数据库的连接池进行处理,在项目中则使用DataSrouce进行数据源的连接。
常用的数据库连接池有两类:C3P0、Druid
1.1 整合C3P0
C3P0是一个开源的JDBC连接池,它实现了数据源与JNDI绑定,支持JDBC3规范和JDBC2的标准扩展,在Hibernate、Spring项目中经常使用。
1.在父项目中添加C3P0的依赖及mysql依赖,修改它的pom.xml文件
在<properties></properties>中添加相关的版本信息
<!-- C3P0的版本属性 -->
< c3p0.version >0.9.5.2 </ c3p0.version >
<!-- mysql 连接的版本属性 -->
< mysql-connector-java.version >5.1.21 </ mysql-connector-java.version >
在<dependencies></dependencies>中添加对应的依赖
<!-- mysql 的依赖 -->
< dependency >
     < groupId > mysql </ groupId >
     < artifactId > mysql-connector-java </ artifactId >
     < version >${ mysql-connector-java.version} </ version >
</ dependency >
<!-- C3P0的依赖 -->
< dependency >
     < groupId >com.mchange </ groupId >
     < artifactId >c3p0 </ artifactId >
     < version >${c3p0.version} </ version >
</ dependency >
2.在父工程下新增一个Maven的new module,xiaoxieboot-integration
3.修改新增项目的pom.xml文件
  < modelVersion >4.0.0 </ modelVersion >
  < parent >
    < groupId >com.xiaoxie </ groupId >
    < artifactId > xiaoxieboot </ artifactId >
    < version >0.0.1-SNAPSHOT </ version >
  </ parent >
  < artifactId > xiaoxieboot-integration </ artifactId >
  < packaging >war </ packaging >
  < dependencies >
      < dependency >
            < groupId > junit </ groupId >
            < artifactId > junit </ artifactId >
            < scope >test </ scope >
      </ dependency >
     
      < dependency >
            < groupId >org.springframework.boot </ groupId >
            < artifactId >spring-boot-starter-test </ artifactId >
            < scope >test </ scope >    
      </ dependency >
     
      < dependency >
            < groupId >org.springframework.boot </ groupId >
            < artifactId >spring-boot-starter-web </ artifactId >
      </ dependency >
     
      < dependency >
            < groupId >org.springframework.boot </ groupId >
            < artifactId >spring-boot- devtools </ artifactId >
      </ dependency >
     
      < dependency >
        < groupId >com.mchange </ groupId >
        < artifactId >c3p0 </ artifactId >
      </ dependency >
      < dependency >
        < groupId > mysql </ groupId >
        < artifactId > mysql-connector-java </ artifactId >
      </ dependency >
  </ dependencies >
 
  < build >
      < plugins >
            < plugin >
                  < groupId >org.apache.maven.plugins </ groupId >
                  < artifactId > maven-war- plugin </ artifactId >
                  < configuration >
                        < warName >xiaoxieboot-web </ warName >
                  </ configuration >
            </ plugin >
      </ plugins >
  </ build >
</ project >
4.在src/main/resource下新增配置文件:application.yml(新增c3p0的配置信息)
c3p0 : #定义c3p0配置
  jdbcUrl:  jdbc: mysql://localhost:3306/test  #数据库连接地址
  user: root  #数据库连接用户名
  password: root  #数据库连接密码
  driverClass:  org.gjt.mm.mysql.Driver #数据库的驱动
  minPoolSize:  1
  maxPoolSize:  1
  maxIdelTime:  3000
  initalPoolSize: 1
 
5.新增关于C3P0的连接池的配置类,com.xiaoxie.config.C3P0DataSourceConfig
package com.xiaoxie.config;
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ Configuration
public class C3P0DataSourceConfig {
       @Bean(name= "dataSource")    //定义一个Bean datasrouce
       @ ConfigurationProperties(prefix= "c3p0")    //定义资源导入前导标记
       public DataSource dataSource() {
             return DataSourceBuilder. create().type(ComboPooledDataSource. class).build();
      }
}
 
6.新增SpringBoot的启动类com.xiaoxie.SpringBootStartApplication
package com.xiaoxie;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class SpringBootStartApplication extends SpringBootServletInitializer {
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
            return builder.sources(SpringBootStartApplication. class);
      }
     
      public static void main(String[] args) {
            SpringApplication. run(SpringBootStartApplication. class, args);
      }
     
}
 
7.在src/test/java中新增测试类:com.xiaoxie.test.DataSourceTest
package com.xiaoxie.test;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.xiaoxie.SpringBootStartApplication;
@SpringBootTest(classes=SpringBootStartApplication. class)
@RunWith(SpringJUnit4ClassRunner. class)
@ WebAppConfiguration
public class DataSourceTest {
       @Autowired
       private DataSource dataSource;
       @Test
       public void testConnection() throws Exception {
            System. out.println( dataSource.getConnection());
      }
}
运行测试类,正常情况下测试类执行成功,且会在控制台中打印出dataSource中获取到的mysql连接
 
1.2 整合Druid
Druid,它是阿里推出的数据库连接池组件,也是一个用于大数据实时查询和分析的高容错、高性能开源分布式系统,可以高效处理大规模的数据并实现快速的查询分析。
1.在父项目中添加Durid的依赖依赖,修改它的pom.xml文件
在<properties></properties>中添加相关的版本信息
       <!-- Druid 的版本 -->
       < druid-version >1.1.6 </ druid-version >
在<dependencies></dependencies>中新增相对durid的依赖
             <!-- Druid 的依赖 -->
             < dependency >
                   < groupId >com.alibaba </ groupId >
                   < artifactId > druid </ artifactId >
                   < version >${ druid-version} </ version >
             </ dependency >
 
2.在新增的maven moudle工程中新装置druid的依赖,修改它的pom.xml文件
      < dependency >
        < groupId >com.alibaba </ groupId >
        < artifactId > druid </ artifactId >
      </ dependency >
 
3.在application.yml配置文件中新增durid的配置信息
spring: 
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource  #配置数据源的操作类型
    driver-class-name:  org.gjt.mm.mysql.Driver #数据库的驱动
    url:  jdbc: mysql://localhost:3306/test  #数据库连接地址
    username: root  #数据库连接用户名
    password: root  #数据库连接密码
    dbcp2:
      min-idle: 1 #连接池最小维持连接数
      initial-size: 1 #初始化提供的连接数
      max-total:  1 #最大连接数
      max-wait-millis:  3000  #超时最大等待时间
 
4.新增durid的配置类:com.xiaoxie.config.DuridDataSourceConfig
package com.xiaoxie.config;
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;
@Configuration
public class DuridDataSourceConfig {
       @Bean(name= "dataSrouce_durid")
       @ ConfigurationProperties(prefix= "spring.datasource")
       public DataSource druid() {
             return new DruidDataSource();
      }
}
 
5.新增测试类:com.xiaoxie.test.DataSourceByDuridTest
package com.xiaoxie.test;
import javax.sql.DataSource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.xiaoxie.SpringBootStartApplication;
@SpringBootTest(classes=SpringBootStartApplication. class)
@RunWith(SpringJUnit4ClassRunner. class)
@WebAppConfiguration
public class DataSrouceByDuridTest {
       @Autowired
       private DataSource dataSrouce_durid;
       @ Test
       public void testConnection() throws Exception {
            System. out.println( dataSrouce_durid.getConnection());
      }
}
运行测试类,正常情况下测试类执行成功,且会在控制台中打印出dataSource中获取到的mysql连接
 
二、SpringBoot整合ORM开发框架
使用Spring整合ORM组件的过程中,为了达到简化的目的,往往都会进行大量的配置。利用SpringBoot可以进一步实现配置的简化。
2.1 SpringBoot整合MyBatis
MyBatis是一款常用且配置简单的ORM开发框架,它与Spring结合后,可以利用Spring的特征实现DAO接口的自动配置。SpringBoot中又对MyBatis框架的整合进行了进一步的简化,在项目中需要引入mybatis-spring-boot-starter依赖支持库。
注意:如果SpringBoot要与ORM开发框架整合前提需要数据库连接池的支持
把c3p0相关的连接池配置去掉,我们使用Durid来做连接池
1.在测试库test,新增数据库表 dept
CREATE TABLE `dept` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `deptno` varchar(50) NOT NULL DEFAULT '' COMMENT '部门编号',
  `deptname` varchar(50) NOT NULL DEFAULT '' COMMENT '部门名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
 
新增测试数据
INSERT INTO `test`.`dept` (`id`, `deptno`, `deptname`) VALUES ('1', '001', '人事部');
INSERT INTO `test`.`dept` (`id`, `deptno`, `deptname`) VALUES ('2', '002', '销售部');
INSERT INTO `test`.`dept` (`id`, `deptno`, `deptname`) VALUES ('3', '003', '技术部');
INSERT INTO `test`.`dept` (`id`, `deptno`, `deptname`) VALUES ('4', '004', '财务部');
 
2.新增一个数据库实体VO对象:com.xiaoxie.vo.Dept
package com.xiaoxie.vo;
import java.io.Serializable;
@SuppressWarnings( "serial")
public class Dept implements Serializable{
       private Long id;
       private String deptno;
       private String deptname;
       public Long getId() {
             return id;
      }
       public void setId(Long id) {
             this. id = id;
      }
       public String getDeptno() {
             return deptno;
      }
       public void setDeptno(String deptno) {
             this. deptno = deptno;
      }
       public String getDeptname() {
             return deptname;
      }
       public void setDeptname(String deptname) {
             this. deptname = deptname;
      }     
}
 
3.集成mybatis,并完成mybatis的配置
在pom.xml中新增mybatis相关的依赖
< dependency >
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.1</version>
</ dependency >
在src/main/resources下新增mybatis文件夹并在其下新增mybatis.cfg.xml配置文件
<? xml version= "1.0" encoding= "UTF-8" ?>
<! DOCTYPE configuration
       PUBLIC "-// mybatis.org//DTD Config 3.0//EN"
< configuration >
       < settings >
             <!-- 开启二级缓存 -->
             < setting name= "cacheEnabled" value= "true" />
       </ settings >
</ configuration >
在application.yml配置中添加mybatis相关配置
mybatis:
  config-location: classpath:mybatis/mybatis.cfg.xml  #mybatis的配置文件位置
  type-aliases-package: com.xiaoxie.vo  #定义所有操作类的别名所在的包
 
4.新增一个DAO接口:com.xiaoxie.dao.IDeptDAO
package com.xiaoxie.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.xiaoxie.vo.Dept;
@Mapper
public interface IDeptDAO {
       @Select( "SELECT id,deptno,deptname FROM dept")
       public List<Dept> findAll();   //查找所有部门信息
}
 
5.新增一个service接口:com.xiaoxie.service.IDeptService
package com.xiaoxie.service;
import java.util.List;
import com.xiaoxie.vo.Dept;
public interface IDeptService {
       public List<Dept> list();
}
 
6.新增一个service的实现类:com.xiaoxie.service.impl.DeptServiceImpl
package com.xiaoxie.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xiaoxie.dao.IDeptDAO;
import com.xiaoxie.service.IDeptService;
import com.xiaoxie.vo.Dept;
@Service
public class DeptServiceImpl implements IDeptService {
       //注入 dao
       @Autowired
       private IDeptDAO deptDAO;
       @Override
       public List<Dept> list() {
             return deptDAO. findAll();
      }
}
 
7.在src/test/java下新增测试类:com.xiaoxe.test.DeptService
package com.xiaoxie.test;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import com.xiaoxie.SpringBootStartApplication;
import com.xiaoxie.service.IDeptService;
import com.xiaoxie.vo.Dept;
@SpringBootTest(classes=SpringBootStartApplication. class)
@RunWith(SpringJUnit4ClassRunner. class)
@WebAppConfiguration
public class DeptServiceTest {
       //注入service
       @Autowired
       private IDeptService deptService;
      
       @Test
       public void testList() {
            List<Dept> depts = deptService.list();
             for (Dept dept : depts) {
                  System. out.println( "ID:" + dept.getId() + " 部门编号:" + dept.getDeptno() + " 部门名称:" + dept.getDeptname());
            }
      }
}
运行测试类,控制台打印的结果如下:
ID:1 部门编号:001 部门名称:人事部
ID:2 部门编号:002 部门名称:销售部
ID:3 部门编号:003 部门名称:技术部
ID:4 部门编号:004 部门名称:财务部
 
2.2 SpringBoot整合JPA开发框架
JPA是官方推出的JAVA持久层操作标准(现在主要使用Hibernate来实现),使用Spring-Data技术和JpaRepository接口技术,也可以达到简化数据层的目的,在SpringBoot中使用SpringDataJPA需要spring-boot-starter-data-jpa依赖库的支持。
在pom.xml中新增JPA相关的依赖
<!-- JPA相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
</dependency>
修改Dept类为如下
package com.xiaoxie.vo;
 
import javax.persistence.*;
import java.io.Serializable;
 
@SuppressWarnings("serial")
@Cacheable(true)
@Entity
public class Dept implements Serializable{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String deptno;
private String deptname;
 
public Long getId() {
return id;
}
 
public void setId(Long id) {
this.id = id;
}
 
public String getDeptno() {
return deptno;
}
 
public void setDeptno(String deptno) {
this.deptno = deptno;
}
 
public String getDeptname() {
return deptname;
}
 
public void setDeptname(String deptname) {
this.deptname = deptname;
}
}
新增一个DAO的接口:com.xiaoxie.dao.Dept_01DAO
package com.xiaoxie.dao;
 
import com.xiaoxie.vo.Dept;
import org.springframework.data.jpa.repository.JpaRepository;
 
public interface IDeptDAO_01 extends JpaRepository<Dept,Long> {
//这里继承了JpaRepository所以已经包含了基础的CRUD
}
注意:这里的接口继承了JpaRepository接口,在这个接口中已经包含了基本的CRUD方法,所在在我们新增的这个类中无需再做接口方法的定义
新增一个service的接口和实现类
接口:com.xiaoxie.service.IDeptService_01
package com.xiaoxie.service;
 
import com.xiaoxie.vo.Dept;
 
import java.util.List;
 
public interface IDeptService_01 {
public List<Dept> list();
}
service的实现类:com.xiaoxie.service.impl.DeptService_01impl
package com.xiaoxie.service.impl;
 
import com.xiaoxie.dao.IDeptDAO_01;
import com.xiaoxie.service.IDeptService_01;
import com.xiaoxie.vo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import java.util.List;
@Service
public class DeptService_01impl implements IDeptService_01 {
@Autowired
private IDeptDAO_01 deptDAO;
 
@Override
public List<Dept> list() {
return deptDAO.findAll();
}
}
修改程序启动主类,增加对Repository扫描配置,在启动主类上新增一个注解
@EnableJpaRepositories (basePackages = "com.xiaoxie.dao" )
新增一个测试类:com.xiaoxie.test.DeptService_01Test
package com.xiaoxie.test;
 
import com.xiaoxie.SpringBootStartApplication;
import com.xiaoxie.service.IDeptService_01;
import com.xiaoxie.vo.Dept;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
import java.util.List;
 
@SpringBootTest(classes = SpringBootStartApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class DeptService_01Test {
@Autowired
private IDeptService_01 deptService01;
@Test
public void testList(){
List<Dept> depts = deptService01.list();
for(Dept dept:depts){
System.out.println("部门编号:" + dept.getDeptno() + " 部门名称:" + dept.getDeptname());
}
}
}
运行测试方法testList后,程序在控制台输出结果如下:
部门编号:001 部门名称:人事部
部门编号:002 部门名称:销售部
部门编号:003 部门名称:技术部
部门编号:004 部门名称:财务部
 
2.3 事务处理
SpringBoot中可以使用PlatformTransactionManager接口来实现事务的统一控制,进行控制的时候也可以也可以使用注解或AOP切面配置形式来完成。
在业务层的方法启用事务控制,在业务层的接口对应的方法上加上类似如下的注解
@Transactional (propagation = Propagation. REQUIRED ,readOnly = true )
在实际的开发过程中会存在多个业务层接口方法,如果每一个添加注解则比较麻烦,可以定义一个业务的配置类
package com.xiaoxie.config;
 
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;
 
import java.util.HashMap;
import java.util.Map;
 
@Configuration //定义配置Bean
@Aspect //使用AOP切面处理
public class TransactionConfig {
//定义事务超时时间()
private static final int TRANSACTION_TIMEOUT = 5;
//定义切面表达式
private static final String AOP_EXPRESSION="execution(* com.xiaoxie.service.*.*(..))";
 
@Autowired //自动注入事务管理对象
private PlatformTransactionManager platformTransactionManager;
 
@Bean("txAdvice")
public TransactionInterceptor transactionConfig(){
//定义只读事务控制
RuleBasedTransactionAttribute readOnly = new RuleBasedTransactionAttribute();
readOnly.setReadOnly(true);
readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
//定义更新事务
RuleBasedTransactionAttribute required = new RuleBasedTransactionAttribute();
required.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
required.setTimeout(TRANSACTION_TIMEOUT);
//定义业务切面
Map<String,TransactionAttribute> transactionAttributeMap = new HashMap<>();
transactionAttributeMap.put("add",required);
transactionAttributeMap.put( "edit" ,required);
transactionAttributeMap.put("delete",required);
transactionAttributeMap.put("get",readOnly);
transactionAttributeMap.put("list",readOnly);
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
source.setNameMap(transactionAttributeMap);
TransactionInterceptor transactionInterceptor = new TransactionInterceptor(platformTransactionManager,source);
return transactionInterceptor;
}
 
@Bean
public Advisor transactionAdviceAdvisor(){
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut,transactionConfig());
}
}
 
三、SpringBoot整合消息服务组件
    消息服务组件常用来做系统整合与异步服务通信,它的基本结构包含生产者、消费者及消息服务的中间件。
     
    常用消息组件主要有两类:JMS标准(ActiveMQ)、AMQP标准(RabbitMQ、Kafka)
 
3.1 SpringBoot整合ActiveMQ消息组件
    ActiveMQ:它是Apache提供的开源消息组件,基于JMS标准实现的。
    在Windows环境下安装ActiveMQ
        下载后解压文件,有两个重要的配置文件在conf的目录下:
        jetty-relm.properties:在这个文件中保存着相关的用户名和密码
        jetty.xml:在这个文件中可以看到相应的端口号
        activemq.xml:在name="openwire"的配置处可以看到对应的服务器地址端口配置
    启动ActiveMQ:
        1、在bin目录下找到win64目录,运行activemq.bat文件
        2、在浏览器中访问: http://localhost:8161/admin
                注意:8161是它的默认端口
        3、输入对应的用户名、密码则进入ActiveMQ的界面
         ​​​​​​​
在程序pom.xml中新增对ActiveMQ的依赖
         <!--ActiveMQ依赖-->
    < dependency >
        < groupId >org.springframework.boot</ groupId >
        < artifactId >spring-boot-starter-activemq</ artifactId >
    </ dependency >
    
在application.yml配置文件中添加ActiveMQ配置信息
         Spring:
        jms:
            pub-sub-domain: false #确认消息类型,true表示topic消息,false表示Queue消息
        activemq:
            user: xiaoxie #连接用户名
            password: xiaoxie #连接密码
            broker-url: tcp://localhost:61616
        
新增一个消息消费监听类:com.xiaoxie.service.consumer.MessageConsumer
package com.xiaoxie.service.consumer;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype. Service ;
@Service
public class MessageConsumer {
@JmsListener (destination = "xiaoxie.msg.queue" )
public void receiveMessage(String msg){
System. out .println( " 【接收消息】: " + msg);
}
}
在这里定义了消息队例:xiaoxie.msg.queue       
 
定义消息生产者业务接口:com.xiaoxie.service.producer.IMessageProducer
package com.xiaoxie.service.producer;
public interface IMessageProducer {
public void send(String msg); //消息发送
}
 
定义消息的业务实现类:com.xiaoxie.service.impl.MessageProducerImpl
package com.xiaoxie.service.impl;
import com.xiaoxie.service.producer.IMessageProducer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype. Service ;
import javax.jms.Destination;
import javax.jms.Queue;
@Service
public class MessageProducerImpl implements IMessageProducer {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
@Autowired
private Queue queue;
@Override
public void send(String msg) {
jmsMessagingTemplate.convertAndSend((Destination) queue,msg);
}
} 
 
定义JMS消息发送配置类,这个类用来配置队列信息:com.xiaoxie.config.ActiveMQConfig
package com.xiaoxie.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation. EnableJms ;
import javax.jms.Queue;
@Configuration
@EnableJms
public class ActiveMQConfig {
@Bean
public Queue queue(){
return new ActiveMQQueue("xiaoxie.msg.queue");
}
}
 
新增测试类进行测试:com.xiaoxie.test.ActiveMQMessageTest
package com.xiaoxie.test;
import com.xiaoxie.SpringBootStartApplication;
import com.xiaoxie.service.producer.IMessageProducer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
@SpringBootTest(classes = SpringBootStartApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class ActiveMQMessageTest {
@Autowired
private IMessageProducer messageProducer ;
@Test
public void testMessage(){
messageProducer.send("你好 ActiveMq!");
}
}
运行测试类,在控制台可以看到输出信息:
【接收消息】:你好 ActiveMq!
 
3.2 SpringBoot整合RabbitMQ消息组件
RabbitMQ组件是在AMQP基础上构建出的新一代企业级消息系统,这个组件由Pivotal公司提供。使用ErLang语言开发。
首先安装ErLang,选择23.0版本
安装完成后,添加相应的环境变量
变量名:ERLANG_HOME
变量值:C:\Program Files\erl-23.0(这个与安装的位置有关系,浏览到安装的目录即可)
在path环境变量中新增一项:%ERLANG_HOME%\bin
完成上面操作后,打开cmd,运行erl如果成功则表示安装成功!如下所示表示ErLang安装成功
其次要安装 rabbitMQ ,选择版本为3.8.9
安装守铖后,添加相应的环境变量
变量名称:RABBITMQ_SERVER
变量值:C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.9(这个与安装的位置有关,浏览到安装的目录即可)
在path环境变量中新增一项:%RABBITMQ_SERVER%\sbin
在RabbitMQ默认安装后没有启用插件,执行下面的命令,启用RabbitMQ的插件管理
rabbitmq -plugins .bat enable rabbitmq_management 这个时候我们在系统服务中会看到有一个RabbitMQ的服务,我们需要重启这个服务
访问如下地址: http://localhost:15672/
用户名和密码可以使用guest(这个是安装后默认的)
可以在登录成功后进入Admin菜单,新增新的用户
在程序中导入相应的依赖
<!-- RabbitMQ依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
 
在springboot的配置文件中新增rabbitmq的相关配置
Spring:
    rabbitmq:
        addresses: 127.0.0.1
        username: xiaoxie
        password: xiaoxie
        virtual-host: /
 
新增消息生产者配置类:com.xiaoxie.config.ProducerConfig
package com.xiaoxie.config;
 
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
* 消息生产配置
*/
@Configuration
public class ProducerConfig {
public static final String EXCHANGE = "xiaoxie.exchange"; //交换空间名称
public static final String ROUTINGKEY = "xiaoxie.routingkey"; //路由key
public static final String QUEUE_NAME = "xiaoxie.queue"; //队列名称
 
@Bean
public Binding bindingExchangeQueue(DirectExchange exchange, Queue queue){
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY);
}
 
//直连的模式连接
@Bean
public DirectExchange getDirectExchange(){
return new DirectExchange(EXCHANGE,true,true);
}
 
@Bean
public Queue queue(){
return new Queue(QUEUE_NAME); //队列信息
}
}
 
新增消费者配置类:com.xaioxie.config.ConsumerConfig
package com.xiaoxie.config;
 
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class ConsumerConfig {
public static final String EXCHANGE = "xiaoxie.exchange"; //交换空间名称
public static final String ROUTINGKEY = "xiaoxie.routingkey"; //路由key
public static final String QUEUE_NAME = "xiaoxie.queue"; //队列名称
 
@Bean
public Queue queue(){
return new Queue(QUEUE_NAME);
}
 
@Bean
public DirectExchange getDirectExchange(){
return new DirectExchange(EXCHANGE,true,true);
}
 
@Bean
public Binding bindingExchangeQueue(DirectExchange exchange,Queue queue){
return BindingBuilder.bind(queue).to(exchange).with(ROUTINGKEY);
}
}
 
新增业务接口用来发送消息:com.xiaoxie.service.producer.IMessageProducerByRabbitmq
package com.xiaoxie.service.producer;
 
public interface IMessageProducerByRabbitmq {
public void send(String msg);
}
 
新增业务接口的实现类:com.xiaoxie.service.impl.MessageProducerByRabbitmqImpl
package com.xiaoxie.service.impl;
 
import com.xiaoxie.config.ProducerConfig;
import com.xiaoxie.service.producer.IMessageProducerByRabbitmq;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
 
@Service
public class MessageProducerByRabbitmqImpl implements IMessageProducerByRabbitmq {
 
@Resource
private RabbitTemplate rabbitTemplate;
 
@Override
public void send(String msg) {
rabbitTemplate.convertAndSend(ProducerConfig.EXCHANGE,ProducerConfig.ROUTINGKEY,msg);
}
}
 
新增消息监听处理类:com.xiaoxie.service.consumer. MessageConsumerByRabbitmq
package com.xiaoxie.service.consumer;
 
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
 
@Service
public class MessageConsumerByRabbitmq {
@RabbitListener(queues = "xiaoxie.queue")
public void receviceMessage(String msg){
System.out.println("***RabbitMQ,接收消息】*** " + msg);
}
}
 
新增测试类:com.xiaoxie.test.RabbitMQMessageTest
package com.xiaoxie.test;
 
import com.xiaoxie.SpringBootStartApplication;
import com.xiaoxie.service.producer.IMessageProducerByRabbitmq;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
@SpringBootTest(classes = SpringBootStartApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class RabbitMQMessageTest {
@Autowired
private IMessageProducerByRabbitmq messageProducerByRabbitmq;
 
@Test
public void testMessage(){
messageProducerByRabbitmq.send("RabbitMQ,你好!");
}
}
运行测试类,程序在控制台会打印出来信息如下:
***【RabbitMQ,接收消息】*** RabbitMQ,你好!
 
四、SpringBoot整合Redis数据库
Redis是用于实现缓存机制的NoSQL数据库,它通过key-value存储,支持高并发访问。
4.1 SpringBoot整合RedisTemplate操作Redis
RedisTemplate是SpringData提供的Redis操作模板,主要以Jedis驱动程序为实现基础,进行数据操作封装,可以直接调用Redis中的各种数据处理命令进行数据库操作。
下载Redis,当前使用版本 redis-2.8.9
解压后进入到目录,运行命令:redis-server redis.window.conf
运行上面的命令后则Redis服务端启动
打开另一个cmd窗口,进入到解压目录,运行命令:redis-cli
这个时候客户端会连接到服务
 
在启动redis的时候出现报“ VirtualAllocEx failed.: unknown error”这个错误,表示启动时分配内存不够,可以使用如下命令启动:.\redis-server.exe .\redis.windows.conf
如果开启了需要密码认证则启动时命令:redis-cli -p 6379 -a xiaoxie
其中xiaoxie则为配置的认证密码,它配置在redis.windows.conf文件中,找到#requirepass的位置,去掉注释并在后面加上需要的认证密码如:xiaoxie
在程序中新增redis相关的依赖
<!-- Redis的引用依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
 
在配置文件application.yml中新增redis的配置
spring:
    redis:
        host: 127.0.0.1
        port: 6379
        password: xiaoxie
        timeout: 1000
        database: 0
    pool:
        max-active: 10
        max-idle: 8
        min-idle: 2
        max-wait: 100
新增测试类使用RedisTemplate模板进行数据处理:com.xiaoxie.test.TestRedisTemplate
package com.xiaoxie.test;
 
import com.xiaoxie.SpringBootStartApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
@SpringBootTest(classes = SpringBootStartApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class TestRedisTemplate {
@Autowired
private RedisTemplate<String,String> redisTemplate;
 
@Test
public void testSet(){
redisTemplate.opsForValue().set("xiaoxie","***Value值】***");
System.out.println(redisTemplate.opsForValue().get("xiaoxie"));
}
}
 
Redis对象序列化操作
RedisTemplate可以操作Redis数据库且可以结合对象序列化操作,实现对象的保存
在程序中定义Redis序列化配置类,实现RedisSerializer接口:com.xiaoxie.util.redis.RedisObjectSerializer
package com.xiaoxie.util.redis;
 
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
 
public class RedisObjectSerializer implements RedisSerializer<Object> {
//对象与字节数组的转换,准备两个转换器
private Converter<Object,byte[]> serializingConverter = new SerializingConverter();
private Converter<byte[],Object> deserializingConverter = new DeserializingConverter();
//定义一个空数组
private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
@Override
public byte[] serialize(Object o) throws SerializationException {
if(o == null){
return EMPTY_BYTE_ARRAY;
}
return serializingConverter.convert(o);
}
 
@Override
public Object deserialize(byte[] bytes) throws SerializationException {
if(bytes == null || bytes.length == 0){
return null;
}
return deserializingConverter.convert(bytes);
}
}
 
新增一个RedisTemplate的配置类:com.xiaoxie.config.RedisConfig
package com.xiaoxie.config;
 
import com.xiaoxie.util.redis.RedisObjectSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
 
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> getRedisTemplate(RedisConnectionFactory factory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
redisTemplate.setKeySerializer(new StringRedisSerializer()); //Key的序列化类型
redisTemplate.setValueSerializer(new RedisObjectSerializer()); //value的序列化类型
return redisTemplate;
}
}
 
新增一个待序列化的VO类:com.xiaoxie.vo.Member
package com.xiaoxie.vo;
 
import java.io.Serializable;
 
public class Member implements Serializable {
private String no;
private String name;
private Integer age;
 
public String getNo() {
return no;
}
 
public void setNo(String no) {
this.no = no;
}
 
public String getName() {
return name;
}
 
public void setName(String name) {
this.name = name;
}
 
public Integer getAge() {
return age;
}
 
public void setAge(Integer age) {
this.age = age;
}
}
 
修改测试类(com.xiaoxie.test.TestRedisTemplate)为如下:
package com.xiaoxie.test;
 
import com.xiaoxie.SpringBootStartApplication;
import com.xiaoxie.vo.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
@SpringBootTest(classes = SpringBootStartApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class TestRedisTemplate {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
 
@Test
public void testSet(){
redisTemplate.opsForValue().set("xiaoxie","***Value值】***");
System.out.println(redisTemplate.opsForValue().get("xiaoxie"));
}
 
@Test
public void testSerialSet(){
//VO对象
Member vo = new Member();
vo.setNo("NO.001");
vo.setName("张三");
vo.setAge(20);
redisTemplate.opsForValue().set("NO.001",vo);
}
 
@Test
public void testSerialGet(){
System.out.println(redisTemplate.opsForValue().get("NO.001"));
}
}
运行测试类中的测试方法:testSerialSet()则会把指定的VO对象序列化
运行测试类中的测试方法:testSerialGet()则根据key去获取对象,运行后控制台可以看到打印对象信息类似如下:
com.xiaoxie.vo.Member@10c171c
 
配置多个RedisTemplate
如果我们需要在程序中连接多个Redis数据源,这个时候不可以依赖于SpringBoot的自动配置实现,只能由用户自已来创建RedisTemplate对象。
在配置文件application.yml中新增两个自己定义的redis的连接配置信息
#自定义Redis连接配置
myRedis:
    redis-one:
        host: 127.0.0.1
        port: 6379
        password: xiaoxie
        timeout: 1000
        database: 0
        pool:
            max-active: 10
            max-idle: 8
            min-idle: 2
            max-wait: 100
    redis-two:
        host: 127.0.0.1
        port: 6379
        password: xiaoxie
        timeout: 1000
        database: 1
        pool:
            max-active: 10
            max-idle: 8
            min-idle: 2
            max-wait: 100
 
在pom.xml文件中添加相关的依赖
<!-- 当自定义Redis配置源时需要新增如下依赖 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
 
新增一个配置类:com.xiaoxie.config.RedisCustomConfig
package com.xiaoxie.config;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
 
import javax.annotation.Resource;
 
@Configuration
public class RedisCustomConfig {
@Resource(name = "redisConnectionFactory")
private RedisConnectionFactory redisConnectionFactoryOne;
@Resource(name = "redisConnectionFactoryTwo")
private RedisConnectionFactory getRedisConnectionFactoryTwo;
 
private JedisConnectionFactory getJedisConnectionFactory(String hostName, String password, int port, int database, int maxActive, int maxIdle, int minIdle, long maxWait) {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName(hostName);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setPassword(password);
jedisConnectionFactory.setDatabase(database);
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(maxActive);
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxWaitMillis(maxWait);
jedisConnectionFactory.setPoolConfig(poolConfig);
jedisConnectionFactory.afterPropertiesSet(); //初始化连接池配置
return jedisConnectionFactory;
}
 
@Bean("redisConnectionFactoryTwo")
public RedisConnectionFactory getGetRedisConnectionFactoryTwo(
@Value("${myRedis.redis-two.host}") String hostName,
@Value("${myRedis.redis-two.password}") String password,
@Value("${myRedis.redis-two.port}") int port,
@Value("${myRedis.redis-two.database}") int database,
@Value("${myRedis.redis-two.pool.max-active}") int maxActive,
@Value("${myRedis.redis-two.pool.max-idle}") int maxIdle,
@Value("${myRedis.redis-two.pool.min-idle}") int minIdle,
@Value("${myRedis.redis-two.pool.max-wait}") long maxWait){
return getJedisConnectionFactory(hostName,password,port,database,maxActive,maxIdle,minIdle,maxWait);
}
 
@Bean("redisConnectionFactory")
public RedisConnectionFactory getGetRedisConnectionFactoryOne(
@Value("${myRedis.redis-one.host}") String hostName,
@Value("${myRedis.redis-one.password}") String password,
@Value("${myRedis.redis-one.port}") int port,
@Value("${myRedis.redis-one.database}") int database,
@Value("${myRedis.redis-one.pool.max-active}") int maxActive,
@Value("${myRedis.redis-one.pool.max-idle}") int maxIdle,
@Value("${myRedis.redis-one.pool.min-idle}") int minIdle,
@Value("${myRedis.redis-one.pool.max-wait}") long maxWait){
 
return getJedisConnectionFactory(hostName,password,port,database,maxActive,maxIdle,minIdle,maxWait);
 
}
 
 
@Bean("redisOne")
public RedisTemplate<String,String> getRedisTemplateOne(){
RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(this.redisConnectionFactoryOne);
return redisTemplate;
}
 
@Bean("redisTwo")
public RedisTemplate<String,String> getRedisTemplateTwo(){
RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(this.getRedisConnectionFactoryTwo);
return redisTemplate;
}
}
注意:原来配置类RedisConfig需要把配置注解注释掉,因为它会和自己定义的置类存在冲突
 
修改测试类com.xiaoxie.test.TestRedisTemplate为如下:
package com.xiaoxie.test;
 
import com.xiaoxie.SpringBootStartApplication;
import com.xiaoxie.vo.Member;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
 
import javax.annotation.Resource;
 
@SpringBootTest(classes = SpringBootStartApplication.class)
@RunWith (SpringJUnit4ClassRunner. class )
@WebAppConfiguration
public class TestRedisTemplate {
@Resource (name = "redisOne" )
private RedisTemplate<String,String> redisOne;
@Resource(name = "redisTwo")
private RedisTemplate<String,String> redisTwo;
 
@Test
public void tesMoreSet(){
redisOne.opsForValue().set("xiaoxie","hello");
redisTwo.opsForValue().set("xiaoxie","hihi");
}
}
 
运行上面的测试方法后,我们可以使用客户端连接redis可以得到看到如下情况
 
 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值