存档2月 2020

spring注解驱动

容器 AnnotationConfigApplicationContext
组件添加
组件赋值
组件注入
AOP
声明事务

原理
BeanFactoryPostProcessor
BeanDefinitionRegistryPostProcessor
ApplicationListener
Spring容器创建过程

WEB
servlet3.o
异步请求

/**
 * 给容器注册组件
 * 1.包扫描+组件标注注解(@Controller...) [我们自己写的]
 * 2.@Bean+ @Configuration [别人写的,导入的第三方包]
 * 3.@Import [快速的给容器中导入组件]
 *      1. @Import({要导入的容器的组件...}) id默认为全类名
 *      2. @ImportSelector 返回要导入的全类名数组
 *      3. ImportBeanDefinitionRegistrar 通过registerBeanDefinitions给容器中增加自己的bean
 * 4.使用spring提供的FactoryBean[工厂Bean]
 *      1.默认获取到的是工厂Bean调用getObject创建的对象
 *      2.通过前缀&获取FactoryBean注入的工厂bean本身
 * 5.@Condition按条件进行判断,满足条件的给容器中注册Bean
 *
 * 赋值方式
 * 1.xml中指定
 * 2.使用Bean创建时指定
 * 3.使用@Value赋值
 *  1.基本数值
 *  2.SpEL #{}
 *  3.配制文件,运行环境变量中的值 ${} 可以使用@PropertySource加载外部配制文件保存到运行的变量中,yml文件先在静态资源中引入
 *
 * 自动装配
 *  spring利用依赖注入DI,完成对IOC容器中各个组件的依赖关系赋值
 *  默认加在ioc容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
 *  1.@Autowired 自动注入 [Spring规范]
 *      AutowiredAnnotationBeanPostProcessor:解析完成自动装配功能
 *      1.默认优先按照类型去容器中找对应的组件:applicationContext.getBean(beanName.Class),找到并赋值
 *      2.如果找到多个相同类型的组件,再将属性的名字作为组件的ID去容器中查找 applicationContext.getBean(beanName),找到并赋值
 *      3.@Qualifier("beanName")明确指定要装配的组件ID,而不傅属性
 *      4.自动装配默认一定要将属性赋值好,没有就会报错,可以使用@Autowired(required = false)没有就不装配
 *      5.@Primary spring进行装配的时候,默认使用首选的Bean,也可以继续使用@Qualifier指定
 *  2.还支持@Resource(JSR250规范)和@Inject(JSR330规范)  [java规范]
 *      1.@Resource 可以和@Autowired一样实现自动装配,默认按照组件名称进行装配,不支持@Primary和@Autowired(required = false)
 *      2.@Inject 使用先导入javax.inject依赖,可以和@Autowired一样实现自动装配,支持@Primary和不支持@Autowired(required = false)
 *  3.@Autowired 可以标在构造器,方法,属性,参数;都是从容器中获取参数组件的值
 *      1.标注在方法,spring容器创建当前对角,就会调用方法,完成赋值,方法使用的参数,自定义类型的值从Ioc容器中获取;@Bean标注的方法创建对象的时候,方法参数的值从容器中获取;默认不写@Autowired效果都是一样的
 *      2.标注在有参构造器时,容器启动调用这有参构造器创建对象,构造器要用的组件,都是从容器中获取;只有一个有参构造器时,可以省略@Autowired,参数位置的组件还是从容器中获取
 *      3.标在参数时,也同2
 *  4.自定义组件想要使用spring容器底层的一些组件(applicationContext,BeanFactory,xxx),自定义组件只需实现xxxAWare接口,有回调的风格,总体参照AWare;
 *   xxxAWare的功能使用xxxAWarePostProcessor后置处理器完成
 *  5.@Profile: spring为我们提供可以根据当前环境,动态激活和切换一系列组件的功能,不指定,在任何环境下都能注册
 *      环境切换:
 *          1使用命令行动态参数-Dspring.profiles.active
 *          2使用代码方式,applicationContext不能使用有参构造器,用无参构造器
 *          //指定主配制类,获得容器
 *         //AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfProfile.class);
 *         AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
 *         //使用无参构造器设置需要激活的环境,一次可以设多个
 *         applicationContext.getEnvironment().setDefaultProfiles("test");
 *         //注册主配制类
 *         applicationContext.register(MainConfigOfProfile.class);
 *         //启动刷新容器
 *         applicationContext.refresh();
 *         log.info("容器创建完成...[{}]",applicationContext);
 *         3.使用配制文件spring.profiles.active=dev
 *      1.加了环境标识的Bean,只有在环境激活的情况下注册到容器中,默认是default环境
 *      2.写在配置类上,只有在只有在环境激活的情况下,整个配置类里面的所有配置才生效
 *      3.没有标注的,在任何环境下都是加载的
 *
 */

Vue.js

Vue官网
Vue CLI
Vue中文
Vue CLI 中文
Vue.js 教程
Webpack打包工具
cnpm install webpack -g
npm i webpack –save-dev
webpack -v

1、独立版本
我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入
2、使用 CDN 方法
以下推荐国外比较稳定的两个 CDN,国内还没发现哪一家比较好,目前还是建议下载到本地。
Staticfile CDN(国内) : https://cdn.staticfile.org/vue/2.2.2/vue.min.js
unpkg:https://unpkg.com/vue/dist/vue.js, 会保持和 npm 发布的最新的版本一致。
cdnjs : https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.8/vue.min.js
3、NPM 方法
$ cnpm install vue
命令行工具
Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用。
  • 全局安装 vue-cli
    $ cnpm install –global vue-cli
    Vue CLI 的包名称由 vue-cli 改成了 @vue/cli。 如果你已经全局安装了旧版本的 vue-cli (1.x 或 2.x),你需要先通过 npm uninstall vue-cli -g 或 yarn global remove vue-cli 卸载它。
    npm install -g @vue/cli
    yarn global add @vue/cli
    vue -V
    本地全局配置一下chormedriver源,打开终端就一个命令:
    npm config set chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver

vue create 项目名
vue ui

创建一个基于 webpack 模板的新项目

Vue CLI 3 和旧版使用了相同的vue命令,所以 Vue CLI 2 (vue-cli) 被覆盖了。如果你仍然需要使用旧版本的vue init功能,你可以全局安装一个桥接工具:安装完后 就还可以使用 vue init 命令
cnpm install -g @vue/cli-init

vue init webpack my-project
– 这里需要进行一些配置,默认回车即可
This will install Vue 2.x version of the template.
For Vue 1.x use: vue init webpack#1.0 my-project
? Project name my-project
? Project description A Vue.js project
? Author runoob test@runoob.com
? Vue build standalone
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Setup unit tests with Karma + Mocha? Yes
? Setup e2e tests with Nightwatch? Yes
vue-cli · Generated “my-project”.
To get started:
cd my-project
npm install
npm run dev
Documentation can be found at https://vuejs-templates.github.io/webpack
进入项目,安装并运行:
$ cd my-project
$ cnpm install
$ cnpm run dev

npm和yarn命令对比npm yarn

npm install
yarn
npm install react –save
yarn add react
npm uninstall react –save
yarn remove react
npm install react –save-dev
yarn add react –dev
npm update –save
yarn upgrade

1.node+webpack+npm(运行环境)
2.vue+vue-router+vuex(框架技术)
3.element-ui、iview、vant(UI组件库)

主流的vue-cli脚手架,在小程序方面用的是mpvue-cli脚手架
采用主流的编辑器,配置相应的eslint语法规范
eslint配置
{
// vscode默认启用了根据文件类型自动设置tabsize的选项
“editor.detectIndentation”:false,
// 重新设定tabsize技术培训1- 111 -本文档使用看云 构建
“editor.tabSize”:2,
// #每次保存的时候自动格式化
“editor.formatOnSave”:true,
// #每次保存的时候将代码按eslint格式进行修复
“eslint.autoFixOnSave”:true,
// 添加 vue 支持
“eslint.validate”: [”javascript”,”javascriptreact”,{“language”:”vue”,”autoFix”:true}],
// #让函数(名)和后面的括号之间加个空格
“javascript.format.insertSpaceBeforeFunctionParenthesis”:true,
// #这个按用户自身习惯选择
“vetur.format.defaultFormatter.html”:”js-beautify-html”,
// #让vue中的js按编辑器自带的ts格式进行格式化
“vetur.format.defaultFormatter.js”:”vscode-typescript”,”vetur.format.defaultFormatter.scss”:”prettier”,”vetur.format.defaultFormatterOptions”:{“js-beautify-html”:{“wrap_attributes”:”force-aligned”
// #vue组件中html代码格式化样式
}}}


错误解决

  1. npm run 运行项目时报错: getaddrinfo ENOTFOUND x86_64-apple-darwin13.4.0
    unset HOST
    sudo vi /etc/hosts加:127.0.0.1 localhost
    修改/etc/hosts,在里面增加一行:127.0.0.1 x86_64-apple-darwin13.4.0

nodejs 模板引擎

模板引擎:
– Jade:面向后端
使用#{}传递变量以及js表达式
属性传递变量直接等于变量即可,不能写成#{}形式,会报错。
‘-‘ 执行符
= 执行符
for循环
使用 ! 渲染dom节点
if判断渲染不同dom节点
jade中switch条件语句和js的语法有点不同,其用case…when…
class属性比较特殊,可以写多个class,jade会自动合并,其他属性不能重复
– Ejs:最常用,最广泛,前后端分离
特点:ejs是非破坏式(非侵入式)引擎,它不改变html的任何语法,可以让我们直接在标签内书写简单、直白的 JavaScript 代码。
<%=变量或表达式%>
ejs中输出data是在回调函数中,不像jade是定义一个变量来接收的
ejs中使用<%=变量名%> 输出数据到模板,如果输出如果含有html标签,<>会被编码(转义)
<%js代码%>
s中使用<%js代码%> 执行js代码, 不会输出,被称作无缓冲的代码。
由于不输出代码,会出现两行空行,可以换成<%_js代码_%>,会自动删除不输出产生的空行
<%-变量或表达式%>
默认使用<%%> 会将<>转义输出,可以使用<%-%>声明不转义输出
include
– handlerbars
模板引擎 Mustache 的扩展
– art-template
介绍 https://aui.github.io/art-template/zh-cn/docs/

Pinpoint 链路监控

链路监控 Pinpoint

https://github.com/naver/pinpoint
安装服务
https://github.com/naver/pinpoint-docker

https://github.com/naver/pinpoint/releases
下载 pinpoint-agent-2.0.2.tar.gz
修改配制文件ponpoint.config
profiler.collector.iP=XX.XX.XXX.XXX #服务器地址
profiler.sampling.rate = 1 采样率1/N,1为100%全部采,20=5%
profiler.applicationservertype=TOMCAT 改SPRING_BOOT 采样服务器类型
查找修改SPRING_BOOT配制中的
profiler.sprintboot.bootstrap.main,增加要监控的main()函数类名
com.xx.xx

配制应用启动参数,指明使用代理
running the application:

-javaagent:$AGENT_PATH/pinpoint-bootstrap-$VERSION.jar
Additionally, Pinpoint Agent requires 2 command-line arguments in order to identify itself in the distributed system:
-Dpinpoint.agentId – uniquely identifies the application instance in which the agent is running on
-Dpinpoint.applicationName – groups a number of identical application instances as a single service

与日志相结合,利用 Transation 与ELK关联

docker-elk

github源码
Bringing up the stack
Clone this repository onto the Docker host that will run the stack, then start services locally using Docker Compose:
$ docker-compose up

5000: Logstash TCP input
9200: Elasticsearch HTTP user:elastic password:changeme
9300: Elasticsearch TCP transport 集群通信保持心跳
5601: Kibana      user:elastic password:changeme

LogStash 离散的日志收集,处理,过滤,格式转换
ElasticSearch 搜索引擎,进行索引,方便检索
Kibana 展示数据

springboot集成logbacku将日志输出到logstash

<!-- https://mvnrepository.com/artifact/net.logstash.logback/logstash-logback-encoder -->
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>6.3</version>
</dependency>

grok表达式

logstash.config
filter{
    grok{
        match => {
            "message" => "%{TIMESTAPM_ISO8601:logTime} %{GREEDYDATA:logThread} %{LOGLEVEL:logLevel} %{GREEDYDATA:loggerClass} - %{GREEDYDATA:logContent}"
        }
    }
}

在ELK前使用消息队列提高可用性,可分享性,如Kafka
配制LogStash从kafka接收
配制springboot项目发送到kafka

<!-- https://mvnrepository.com/artifact/com.github.danielwegener/logback-kafka-appender -->
<dependency>
    <groupId>com.github.danielwegener</groupId>
    <artifactId>logback-kafka-appender</artifactId>
    <version>0.2.0-RC2</version>
</dependency>
建立日志配制文件logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>

    <!--将日志发送到LOGSTASH-->
   <!-- <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashAccessTcpSocketAppender">
        <destination>localhost:5000</destination>-->
        <!--整个日志信息转为一个JSON发送-->
       <!-- <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/>-->
        <!--自定义一个发送格式-->
       <!-- <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>-->

    <!--将日志发送到kafka-->
    <appender name="KAFKA" class="com.github.danielwegener.logback.kafka.KafkaAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <topic>test</topic>
        <keyingStrategy class="com.github.danielwegener.logback.kafka.keying.NoKeyKeyingStrategy"/>
        <deliveryStrategy class="com.github.danielwegener.logback.kafka.delivery.AsynchronousDeliveryStrategy"/>
        <producerConfig>bootstrap.servers=192.168.88.108:9092</producerConfig>
        <appender-ref ref="CONSOLE"/>
    </appender>

    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <root level="INFO">
        <!--<appender-ref ref="LOGSTASH"/>-->
        <appender-ref ref="KAFKA"/>
        <appender-ref ref="CONSOLE"/>
    </root>

</configuration>

Prometheus

官网 https://prometheus.io/
github源码:https://github.com/prometheus/prometheus
docker镜像:https://hub.docker.com/r/prom/prometheus

适用范围:
Prometheus使用定时采样,常常用于在服务集群中采集实时监控数据进行图表分析

不适范围:
不能保证100%的数据完整,不适用于高精度要求的统计分析。

四种指标模型
Counter:只增不减的计数器,非常适合请求的个数,任务计数器, 出现的错误个数,产品的统计数等
Gauge:可增可减的仪表盘,可用于即时测量值指标
Histogram:自带buckets区间分布统计图,还提供了所有观测值的和
Summary:客户端定义的数据分布统计图,计算滑动时间窗口上的可配置分位数

Prometheus使用PromQL查询表达式进行数据查询
rate(is_request_counter{service=”/datav/ks”,method=”GET”}[1m])
单位时间内的计数

Prometheus可自定义告警规则进行告警。告警的触发条件是一个查询表达式。告警规则可配置在Prometheus服务端的配置文件中。

Prometheus 采取拉取数据进行数据采集.
其中pushgateway中间数据处理接收数据供server拉取
自带简单的webUI,有更高级图表Grafana,也可自写API调取数据

推送->Alertmanager->pagerduty/mail/etc

Docker方式安装
docker run -d –name prometheus -p 9090:9090 -v ~/prometheus/:/etc/prometheus/ prom/prometheus:V2.4.3

docker run -d –name grafana -p 3000:3000 -v ~/grafana/config/grafana.ini:/etc/grafana/grafana.ini -v ~/grafana/provisioning/:/etc/grafana/provisioning/ -env_file ~/grafana/config.monitoring grafana/grafana:5.2.4

default admin user is admin/admin.
提供数据

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <!--<version>2.1.6.RELEASE</version>-->
        </dependency>
         <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>

management:
  endpoint:
    prometheus: #启用prometheus
      enabled: true
  endpoints:
    web:
      exposure:
        include: #只对外显示以下信息
          - prometheus
          - info
          - health

放行不用认证
@Configuration
public class ActuatorSecurityConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 所有的端点状态信息不需要身份认证
                .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
                // 其它的都需要认证访问
                .anyRequest().authenticated();
    }
}

Zookeeper

官网

https://zookeeper.apache.org/
下载包安装先修改配制文件
cp -f zoo_sample.cfg zoo.cfg
./zkServer.sh start/stop
./zkCli.sh 客户端工具,默认连接本机2181端口

建议docker pull zookeeper
https://hub.docker.com/_/zookeeper

docker run --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 -p 8080:8080 --restart always -d zookeeper

Sentinel  限流

增加依赖
<!--阿里Sentinel限流-->
        <!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-core -->
        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-core</artifactId>
            <version>1.7.1</version>
        </dependency>
声明资源
try(Entry entry = SphU.entry("getRole")) {
            //Sentinel要保护的资源定义
            response = restTemplate.postForObject("http://RBAC/role/test",  Arrays.asList("157875196366160022"),String.class);
            log.info("response={}", response);
        }catch (BlockException e) {
            log.info("限流");
            e.printStackTrace();
        }
定义规则

针对资源定义流控,限流,降级,熔断的规则

Component
public class SentinelConfig implements ApplicationListener<ContextRefreshedEvent> {

    /**
     * 系统启动完成后就执行的代码,在这里声明流控规则
     * @param contextRefreshedEvent
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        FlowRule rule = new FlowRule();
        rule.setRefResource("getRole");
        //QPS第秒请求的数量
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        //每秒10个
        rule.setCount(10);
        //添加到FlowRuleManager
        List<FlowRule> rules = new ArrayList<FlowRule> ();
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}
日志

当前用户下~/logs/csp/

DASHBOARD

https://github.com/alibaba/Sentinel
默认用户名密码都是sentinel
how to download
docker pull bladex/sentinel-dashboard:tagname
how to start
docker run –name sentinel -d -p 8858:8858 -d bladex/sentinel-dashboard:tagname
how to login web-dashboard
visit: http://localhost:8858/
account and password: [sentinel sentinel]
just enjoy 🙂
github
https://github.com/chillzhuang/SpringBlade
website
https://bladex.vip

docker install dashboard
docker run --name sentinel  -d -p 8858:8858  bladex/sentinel-dashboard:1.7.1
springboot
<dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-transport-simple-http</artifactId>
            <version>1.7.1</version>
        </dependency>
项目启动参数
-Dcsp.sentinel.dashboard.server=DASHBOARD的服务地址
使用Spring Cloud Starter Alibaba Sentinel
1. 依赖
<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-sentinel -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>
2. 配制
spring:
  application:
    #应用名
    name: client
  cloud:
    #sentinel流控
    sentinel:
      transport:
        port: 8719
        dashboard: http://192.168.88.108:9001
3. 使用注解定义资源
@GetMapping("/role3")
    //Sentinel要保护的资源定义
    @SentinelResource(value = "getRole",blockHandler = "doOnBlock")
    public Result role3(@AuthenticationPrincipal String userName){
        String response = response = restTemplate.postForObject("http://RBAC/role/test",  Arrays.asList("157875196366160022"),String.class);
        return Result.success(response);
    }
    public Result doOnBlock(@AuthenticationPrincipal String userName,BlockException exception) throws InterruptedException {
        log.info("userName [{}] doOnBlock By [{}]",userName,exception.getClass().getSimpleName());
        return Result.success(userName);
    }
在面版中配制规则更方便
数据持久化

可用zookeeper,apollo,nacos按自己需求配制
1. 下载dashboard源码,选择分支,导入项目,
– 修改pom中相应的 publisher sample 去掉scope
– 实现rule下的数据接口,样列在test包下的rule中,COPY
– 修改controller/v2/FlowControllerV2.java
ruleProvider的注入改flowRuleZookeeperProvider
rulePublisher的注入改flowRuleZookeeperPublisher
– 修改配制文件
application.properties更改默认的用户名及密码,服务器运行端口等
– 修改表态页面
webapp/resources/app/scripts/directives/sidebar/sidebar.html 流控规则的dashboard.flowv1->flow
– 修改数据地址
NacosConfig ConfigService

  1. 修改应用项目
    增加数据源依赖
<!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-datasource-zookeeper -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-zookeeper</artifactId>
    <version>1.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba.csp/sentinel-datasource-nacos -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.1</version>
    <scope>test</scope>
</dependency>

增加配制文件
#sentinel规则zoopeeker数据源地址

sentinel:
  zookeeper:
    address: 192.168.88.108:2781
    path: /sentinel_rule_config

去掉手动的规则SentinelConfig,改读取配制文件

@Component
public class SentinelConfig {

    @Value("${sentinel.zookeeper.address}")
    private String zkServer;

    @Value("${sentinel.zookeeper.path}")
    private String zkPath;

    @Value("${spring.application.name}")
    private String appName;
    ......
}

@Valid@Validated数据校验

@Valid是使用hibernate validation的时候使用
@valid,java的jsr303声明了这类接口,hibernate-validator对其进行了实现

@Validated 是只用spring Validator 校验机制使用

空检查

@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
用在基本类型上 不能为null,但可以为empty,没有Size的约束
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
只用于String,不能为null且trim()之后size>0
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
String类、Collection、Map、数组,是不能为null或者长度为0的(String Collection Map的isEmpty()方法)

Booelan检查

@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false

长度检查

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) Validates that the annotated string is between min and max included.

日期检查

@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则

数值检查,

建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为””,Integer为null

@Min 验证 Number 和 String 对象是否大等于指定的值
@Max 验证 Number 和 String 对象是否小等于指定的值
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
@Range(min=10000,max=50000,message=”range.bean.wage”)
private BigDecimal wage;
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber信用卡验证
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)

@NotNull(message = "appId不能为空", groups = {AccountGroup.Update.class})
private Integer appId;

BindingResult bindingResult