dubbo

定义接口

public interface HelloService {
public String hello(String str);
}

发布到本地仓库

安装zookeeper

安装java

新建data目录

进入到conf目录,然后复制zoo_sample.cfg为zoo.cfg

dataDir=C:\wzxProgramData\zookeeper_data

进入 bin 目录,执行 zkServer.cmd

服务端

<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>

<dependency>
<groupId>com.wzx</groupId>
<artifactId>dubboApi</artifactId>
<version>1.0</version>
</dependency>
spring.application.name=dubbo-provider
spring.dubbo.server=true
spring.dubbo.registry=zookeeper://127.0.0.1:2181
import com.alibaba.dubbo.config.annotation.Service;
import com.wzx.service.HelloService;
import org.springframework.stereotype.Component;

@Service(interfaceClass = HelloService.class)
@Component
public class HelloServiceImpl implements HelloService {
@Override
public String hello(String str) {
System.out.println("hello");
return "hello "+str;
}
}
@EnableDubboConfiguration

客户端

<dependency>
<groupId>com.alibaba.spring.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>

<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>

<dependency>
<groupId>com.wzx</groupId>
<artifactId>dubboApi</artifactId>
<version>1.0</version>
</dependency>
server.port=8081
spring.application.name=dubbo-custom
spring.dubbo.registry=zookeeper://127.0.0.1:2181
import com.alibaba.dubbo.config.annotation.Reference;
import com.wzx.service.HelloService;
import org.springframework.stereotype.Service;

@Service
public class HelloServiceClient {
@Reference
HelloService helloService;
public String hello(String str){
return helloService.hello(str);
}

}
@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
HelloServiceClient helloServiceClient;
@RequestMapping("/hello")
public String hello(){
return helloServiceClient.hello("hello");
}
}
@EnableDubboConfiguration

dubbo-admin

https://github.com/apache/incubator-dubbo-admin/tree/master

server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
spring.root.password=root
spring.guest.password=guest

dubbo.registry.address=zookeeper://127.0.0.1:2181

http://127.0.0.1:7001/

用户名/密码:root/root

dubbo-monitor

dubbo.container=log4j,spring,registry,jetty-monitor
dubbo.application.name=simple-monitor
dubbo.application.owner=dubbo
#dubbo.registry.address=multicast://224.5.6.7:1234
dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.protocol.port=7070
dubbo.jetty.port=8090
dubbo.jetty.directory=${user.home}/monitor
dubbo.charts.directory=${user.home}/monitor/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN

http://127.0.0.1:8090/

参考资料

https://www.jianshu.com/p/f7037105db46

https://github.com/alibaba/dubbo-spring-boot-starter/blob/master/README_zh.md

https://www.cnblogs.com/jaycekon/p/SpringBootDubbo.html

https://blog.csdn.net/pri_sta_pub/article/details/79087592

https://www.cnblogs.com/Bruce3555/p/7255441.html

https://blog.csdn.net/qq_31748587/article/details/84883504

https://blog.csdn.net/zzqw199012/article/details/79643878

spring boot配置文件、注解

入口类

@SpringBootApplication: 应用程序开始运行的方法,是一个组合注解,包含@EnableAutoConfiguration、@ComponentScan、@SpringBootConfiguration

@SpringBootConfiguration: 标明该类使用Spring基于Java的注解,而不是基于xml的配置。对@Configuration进行了包装。

@EnableAutoConfiguration: 开启自动配置功能,包含@Import({EnableAutoConfigurationImportSelector.class}),@Import借助EnableAutoConfigurationImportSelector将所有符合条件的@Configuration配置加载到SpringBoot的Ioc容器ApplicationContext中。

@ComponentScan: 启动组件扫描,开发的Bean可以被自动发现并注入ApplicaitonContext中。

测试类

@RunWith(SpringRunner.class): 继承自SpringJUnit4ClassRunner,配合SpringRunner使用Junit的参数化功能。

@SpringBootTest: 引用入口类的配置来运行测试类。

@Test: Junit单元测试方法

起步依赖

起步依赖会引入相关的传递依赖,如果不想用默认的依赖,可以用<exclusions>排除传递依赖

spring-boot-starter-parent: 作为父依赖,提供常用的Maven默认依赖,如资源过滤、插件设置、编译级别、测试框架,常用的包可以省去version标签。

spring-boot-starter-web: 使用Spring MVC构建Web应用,使用Tomcat作为嵌入式容器,包含spring-web、spring-webmvc等

spring-boot-starter-test: 常规的测试依赖,包括JUnit、Hamcrest、Mockito、spring-test

spring-boot-maven-plugin: 为spring-boot提供maven操作,可以打包为jar、war

spring-boot-starter-logging: 日志功能

spring-boot-starter-thymeleaf: 使用thymeleaf构建MVC Web应用

spring-boot-starter-jdbc: 使用jdbc与tomcat jdbc连接池

spring-boot-starter-data-jpa: 使用spring数据Jpa和Hibernate

spring-boot-starter-data-redis: redis key-value数据存储、spring data redis、jedis客户端

spring-boot-starter-log4j2: 提供log4j2的日志功能

spring-boot-starter-mail: 邮件功能

spring-boot-starter-activemq: 使用activeMQ的JMS

spring-boot-starter-data-mongodb: 使用mongoDB面向文档的数据库、spring data mongoDB

spring-boot-starter-actuator: 应用健康与健康功能

spring-boot-starter-security: spring security

spring-boot-starter-dubbo: 提供dubbo框架

mysql

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/test
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver

JdbcTemplate:
execute方法:可以用于执行任何SQL语句,一般用于执行DDL语句;
update方法及batchUpdate方法:update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
query方法及queryForXXX方法:用于执行查询相关语句;
call方法:用于执行存储过程、函数相关语句。

List result = jdbcTemplate.query(listSql, new RowMapper() {  
@Override  
public Map mapRow(ResultSet rs, int rowNum) throws SQLException {  
     Map row = new HashMap();  
        row.put(rs.getInt(“id”), rs.getString(“name”));  
       return row;  
   }});

Spring Data JPA

CrudRepository: 基本的增删改查
PagingAndSortingRepository: 基本的分页和排序
JpaRepository: 批量操作,通常使用这个接口

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

@Entity: 持久化POJO类,javax.persistence.Entity

@Table(name=”user”): 对象映射到的数据库的表名,javax.persistence.Table

@Id: 表的主键,javax.persistence.Id

@Service: 表明该类是服务类,会被自动扫描,org.springframework.stereotype.Service

@Component: 会被自动扫描,泛指组件,org.springframework.stereotype.Component

@Repository: 持久层组件,即DAO组件,会被自动扫描

@Resource(name=”userRepository”): 可以写在字段上,也可以写在setter方法上,默认使用字段名进行查找,找不到匹配的bean时,会按类型进行装配。一旦指定name属性,只会按名称进行装配。javax.annotation.Resource

@Autowired(required=false): 默认按类型进行装配,默认对象不为null。可与@Qualifier配合使用,按名称装配
@Autowired
@Qualifier(“userRepository”)

Thymeleaf

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

spring:
thymeleaf:
mode: HTML5
encoding: UTF-8
content-type: text/html
# 开发时配置为false,避免修改模板后重启服务器
cache: false
prefix: classpath:/templates/

@Controller: 表示控制层类,会被自动扫描

@RequestMapping: 请求地址映射,可以用于类和方法,用于类表示所有方法的父路径

@ResponseBody: 返回json或其他对象

过滤器

Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。基于回调函数实现。

@WebFilter(filterName=”userFilter”,urlPatterns=”/*”): 声明类为过滤器,filterName等价于<filter-name>,urlPatterns等价于<url-pattern>,value等价于urlPatterns属性,但不能同时使用。

过滤器要实现Filter接口,重写init、doFilter、destroy方法,在doFilter中要显示推动过滤器链,filterChain.doFilter(servletRequest,servletResponse)

@ServletComponentScan: 注解在入口类,扫描Servlet、Filter、Listener

可以通过ServletRegistrationBean、FilterRegistrationBean、ServletListenerRegistrationBean注册Bean

监听器

用于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁事件。用于在事件发生前、发生后做一些必要的处理。

@WebListener:声明一个类为监听器类,并被扫描

ServletContextListener: 对应application,监听web应用的生命周期

HttpSessionListener:对应与session

ServletRequestListener: 对应request

绑定到session上的某个对象的状态:ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener

拦截器

定义实现HandlerInterceptor 的拦截器类,实现preHandle、postHandle、afterCompletion

定义实现WebMvcConfigurer 的配置类,在addInterceptors中添加拦截器

拦截器与过滤器


Redis

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

spring:
redis:
database: 0
host: localhost
port: 6379
password: 123456

RedisTemplate、StringRedisTemplate: Spring Data Redis提供的模板类,用来对数据进行操作,有opsForValue、opsForList、opsForSet、opsForZSet、opsForHash

Quartz

Job: 每次执行任务时新建一个实现Job接口的类,需要实现execute方法

JobDetail: Job的静态信息,如名字、描述、关联的监听器信息

Trigger: 触发器,描述Job执行的规则,一个Trigger只对应一个JobDetail,JobDetail可以有多个Trigger。SimpleTrigger用于执行一次或固定时间间隔执行,CronTrigger用于复杂的执行方式

Scheduler管理Quartz的运行环境,将Trigger绑定到JobDetail中

<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>

spring-mvc.xml:
<import resource=”spring-quartz.xml”/>

spring-quartz.xml:
<bean id=”myJob” class=”com.wzx.quartz.MyJob”/>
<bean id=”jobDetail” class=”org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean”>
<property name=”targetObject”>
<ref bean=”myJob”/>
</property>
<property name=”targetMethod”>
<value>run</value>
</property>
</bean>
<bean id=”myTrigger” class=”org.springframework.scheduling.quartz.CronTriggerFactoryBean”>
<property name=”jobDetail”>
<ref bean=”jobDetail”/>
</property>
<property name=”cronExpression”>
<value>0/10 * * * * ?</value>
</property>
</bean>
<bean id=”scheduler” class=”org.springframework.scheduling.quartz.SchedulerFactoryBean”>
<property name=”triggers”>
<list>
<ref bean=”myTrigger”/>
</list>
</property>
</bean>

注解方式需要在定时器类上添加:@Component、@Configurable、@EnableScheduling

@Configurable:相当于xml配置文件

@EnableScheduling: 开启对计划任务的支持

@Scheduled(cron=”*/5 * * * * *”): 定时任务,注解在方法上

Email

发件人使用SMTP协议发送到服务器A
服务器A发送到服务器B
收件人使用POP3协议从服务器B接收邮件

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

spring:
mail:
host: smtp.163.com
username: wzx@163.com
password: 123456
default-encoding: UTF-8
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true

@Value(”${spring.mail.username}”): 将配置文件的配置设置到属性中

JavaMailSender: 邮件发生接口,调用send函数发生MimeMessage类

Mybatis

<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>

mybatis:
mapper-locations: classpath:/mappers/*Mapper.xml
type-aliases-package: com.wzx.dao

@Mapper: mybatis根据接口定义与Mapper文件中的sql语句动态创建接口实现

@Param: 在xml文件中可以采仪#{}的方式访问@Param的参数

<mapper>: 使用namespace属性绑定Dao接口

<select>: 编写select语句,映射查询语句

<resultMap>: 描述如何将结果集映射到Java对象

ActiveMQ

JMS: Java Message Service,提供消息的创建、发送、读取的一组接口和响应语法,是一种与厂商无关的api,支持点对点和发布-订阅模型。

点对点:生产者、消费者、队列,消息可以异步传输,发送者和接收者没有时间上的依赖性,每个消息只有一个消费者。

发布-订阅:发布者、订阅者、主题,每个消息可以有多个消费者,发布者和订阅者有时间上的依赖性,消息可以不做任何处理

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>

spring:
activemq:
broker-url: tcp://localhost:61616
in-memory: true
pool:
enabled: false
packages:
trust-all: true

JmsMessageTemplate: 将消息发送到队列

@JmsListener(destination=”my.queue”): 注解在方法上,监听my.queue上的消息,类使用@Component注解,用于扫描

异步调用

除了使用多线程,还可以使用异步调用。

@Async: 注解在方法上,异步调用方法

@EnableAsync: 注解在入口类,开启异步调用

404、异常

EmbeddedServletContainerCustomizer: 是个Bean,customize方法中添加404页面

@ControllerAdvice(basePackages={“com.wzx”}): 定义统一的异常处理类

@ExceptionHandler({WzxException.class}): 注解在方法上,定义针对的异常类型

重试机制

try-catch-redo: 在catch中重试

try-catch-redo-retry: try中延迟重试、catch中延迟重试

Spring-Retry: 利用注解将正常逻辑与重试逻辑解耦

<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>

@Retryable(value={WzxException.class},maxAttempts=5,backoff=@Backoff(delay=5000,multiplier=2)):
注解在方法上。
value指定出现那些异常进行重试,maxAttempts为最大重试次数,默认最大3次,delay为重试的延迟时间,multiplier表示上一次延迟时间是这一次的倍数。

@EnableRetry: 入口类开启重试

MongoDB

<dependency>
<groupId>org.springframeworkd.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

spring:
data:
mongodb:
host: localhost
port: 27017
database: test

MongoRepository: 接口,继承自Repository,提供MongoDB的增删改查

spring security

AuthenticationManager: 身份认证机构,识别访问者

AccessDecisionManager: 控制机构,定义访问者可以访问那些资源

AbstractSecurityInterceptor: 拦截器

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>1.5.9.RELEASE<version>
</dependency>

@EnableWebSecurity: 开启Security,注解在配置类上

WebSecurityConfigureAdapter: 配置类,configure方法配置路由策略和访问权限,configureGlobal方法添加访问者

UserDetailsService: 访问者的服务类,loadUserByname返回用户名、密码、角色

参考资料

《一步一步学Spring Boot2 微服务项目实战》 黄文毅

https://blog.csdn.net/dyllove98/article/details/7772463

https://blog.csdn.net/qq_22172133/article/details/81192040

https://blog.csdn.net/fansili/article/details/78740877

https://blog.csdn.net/yyqhwr/article/details/80986056

https://www.cnblogs.com/hhhshct/p/8808115.html

https://blog.csdn.net/heweimingming/article/details/79993591

spring boot 事务

原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

原子性其实并不能保证一致性的。再多个事务并行进行的情况下,即使保证每一个事务的原子性,任然可能导致数据不一致的结果。

spring事务的配置文件由三部分组成:
DataSource
TransactionManager
代理机制

@Transactional: org.springframework.transaction.annotation.Transactional
事务的传播行为、隔离级别、超时时间、是否只读、回滚规则
开启事务可以注解在类和方法上,注解在类上表示此类的所有public方法都开启事务

@Transactional(propagation=Propagation.REQUIRES_NEW,
isolation=Isolation.READ_COMMITTED,
noRollbackFor={UserAccountException.class},
readOnly=true, timeout=3)

propagation: 定义事务传播行为
isolation: 定义定义隔离级别
timeout: 定义事务过期时间
readOnly: 定义是否为只读事务
RollbackFor: 指定那些异常引起回滚
noRollbackFor: 指定那些异常不可以引起回滚

@EnableTransactionManagement: 开启事务支持,Spring会扫描注解了@Transactional的方法和类,在spring boot中无需显示使用此注解,spring boot默认为JPA、JDBC、Mybatis开启了事务

begin: 开启事务
commit: 提交事务
rollback: 回滚
suspend: 挂起事务
resume: 恢复事务
setSavepoint: rollback可以回滚到保存的节点

传播行为:
PROPAGATION_REQUIRED 表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务
PROPAGATION_SUPPORTS 表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行
PROPAGATION_MANDATORY 表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常
PROPAGATION_REQUIRED_NEW 表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
PROPAGATION_NOT_SUPPORTED 表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager
PROPAGATION_NEVER 表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常
PROPAGATION_NESTED 表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。注意各厂商对这种传播行为的支持是有所差异的。可以参考资源管理器的文档来确认它们是否支持嵌套事务

嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

脏读(Dirty reads)脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
不可重复读(Nonrepeatable read)不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。
幻读(Phantom read)幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。

隔离性分为四个级别:
读未提交:(Read Uncommitted),读写后立即释放锁,即释放锁发生在commit之前,会导致脏读
读已提交(Read Committed) 大多数数据库默认的隔离级别,commit后释放锁,会导致不可重复读、幻读
可重复读(Repeatable-Read) mysql数据库所默认的级别,事务内读取会返回第一次读取的内容
序列化(serializable)锁住表

ISOLATION_DEFAULT 使用后端数据库默认的隔离级别
ISOLATION_READ_UNCOMMITTED 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
ISOLATION_SERIALIZABLE 最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的

参考资料

《一步一步学Spring Boot2 微服务项目实战》 黄文毅

https://blog.csdn.net/trigl/article/details/50968079

https://blog.csdn.net/tianyuxingxuan/article/details/75197452

https://www.zhihu.com/question/30272728/answer/132403859

Spring Boot目录结构

目录结构

/src/main/java: java源文件

/src/main/resources: 配置文件、静态资源文件、页面文件

/src/main/resources/static: 静态资源

/src/main/resources/application.properties: 配置文件

/src/main/resources/templates: 模板文件

/src/test/java: java单元测试源文件

/target: 编译后的class文件、配置文件

配置文件

application.properties优先级高于application.yml

application.properties:
server.port=8080

application.yml:
server:
port:8080

参考资料

《一步一步学Spring Boot2 微服务项目实战》 黄文毅

spring boot环境搭建

安装jdk

安装maven

修改conf/setting.xml

<localRepository>C:\mavenLib</localRepository>

<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>

安装idea

修改file/setting/Build,Execution,Deployment/Build Tools/Maven

设置User settings file和Local repository

新建Spring Boot项目

选择file/new/project/Spring Initializr

修改项目名称、包名等

勾选Web

参考资料

《一步一步学Spring Boot2 微服务项目实战》 黄文毅

https://www.cnblogs.com/gongxr/p/7930453.html

https://www.cnblogs.com/waterlufei/p/6498526.html

http://idea.lanyus.com/