借鉴:https://blog.csdn.net/Harry_ZH_Wang/article/details/79691994

   https://blog.csdn.net/ignorewho/article/details/80702827

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

事件监听介绍

  Spring提供5种标准的事件监听:

  1. 上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在调用ConfigurableApplicationContext接口中的refresh()方法时被触发。
  2. 上下文开始事件(ContextStartedEvent):当容器ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。
  3. 上下文停止事件(ContextStoppedEvent):当容ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。
  4. 上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。
  5. 请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

  Spring Boot扩展了Spring的ApplicationContextEvent,提供了四种事件:

  1. ApplicationStartedEvent :spring boot启动开始时执行的事件
  2. ApplicationEnvironmentPreparedEvent:spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。
  3. ApplicationPreparedEvent:spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。
  4. ApplicationFailedEvent:spring boot启动异常时执行事件

事件监听实现

一、Spring Boot提供的四种事件

  1、事件监听器

  不多说,直接上代码

  ApplicationStartedEvent事件

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener; /**
* Spring Boot扩展了Spring的ApplicationContextEvent,提供了四种事件:
* ApplicationStartedEvent :spring boot启动开始时执行的事件
* ApplicationEnvironmentPreparedEvent:spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。
* ApplicationPreparedEvent:spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。
* ApplicationFailedEvent:spring boot启动异常时执行事件
* @ClassName: CustomApplicationListenerStarted
* @author OnlyMate
* @Date 2018年9月14日 下午4:22:43
*
*/
public class CustomApplicationListenerStarted implements ApplicationListener<ApplicationStartedEvent> {
private Logger logger = LoggerFactory.getLogger(CustomApplicationListenerEnvironmentPrepared.class); @Override
public void onApplicationEvent(ApplicationStartedEvent event) {
logger.info("CustomApplicationListenerStarted ==> onApplicationEvent method");
} }

ApplicationEnvironmentPreparedEvent事件

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener; /**
* Spring Boot扩展了Spring的ApplicationContextEvent,提供了四种事件:
* ApplicationStartedEvent :spring boot启动开始时执行的事件
* ApplicationEnvironmentPreparedEvent:spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。
* ApplicationPreparedEvent:spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。
* ApplicationFailedEvent:spring boot启动异常时执行事件
* @ClassName: CustomApplicationListenerEnvironmentPrepared
* @author OnlyMate
* @Date 2018年9月14日 下午4:22:43
*
*/
public class CustomApplicationListenerEnvironmentPrepared implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
private Logger logger = LoggerFactory.getLogger(CustomApplicationListenerEnvironmentPrepared.class); @Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
logger.info("CustomApplicationListenerEnvironmentPrepared ==> onApplicationEvent method : {}", getClass().getSimpleName());
}

ApplicationPreparedEvent事件

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.context.ApplicationListener; /**
* Spring Boot扩展了Spring的ApplicationContextEvent,提供了四种事件:
* ApplicationStartedEvent :spring boot启动开始时执行的事件
* ApplicationEnvironmentPreparedEvent:spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。
* ApplicationPreparedEvent:spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。
* ApplicationFailedEvent:spring boot启动异常时执行事件
* @ClassName: CustomApplicationListenerPrepared
* @author OnlyMate
* @Date 2018年9月14日 下午4:22:43
*
*/
public class CustomApplicationListenerPrepared implements ApplicationListener<ApplicationPreparedEvent> {
private Logger logger = LoggerFactory.getLogger(CustomApplicationListenerEnvironmentPrepared.class); @Override
public void onApplicationEvent(ApplicationPreparedEvent event) {
logger.info("CustomApplicationListenerPrepared ==> onApplicationEvent method : {}", getClass().getSimpleName());
} }

ApplicationFailedEvent事件

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.context.ApplicationListener; /**
* Spring Boot扩展了Spring的ApplicationContextEvent,提供了四种事件:
* ApplicationStartedEvent :spring boot启动开始时执行的事件
* ApplicationEnvironmentPreparedEvent:spring boot 对应Enviroment已经准备完毕,但此时上下文context还没有创建。
* ApplicationPreparedEvent:spring boot上下文context创建完成,但此时spring中的bean是没有完全加载完成的。
* ApplicationFailedEvent:spring boot启动异常时执行事件
* @ClassName: CustomApplicationListenerFailed
* @author OnlyMate
* @Date 2018年9月14日 下午4:22:43
*
*/
public class CustomApplicationListenerFailed implements ApplicationListener<ApplicationFailedEvent> {
private Logger logger = LoggerFactory.getLogger(CustomApplicationListenerEnvironmentPrepared.class); @Override
public void onApplicationEvent(ApplicationFailedEvent event) {
logger.info("CustomApplicationListenerFailed ==> onApplicationEvent method : {}", getClass().getSimpleName());
} }

  2、注册事件监听器

import java.util.HashSet;
import java.util.Set; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext; import com.only.mate.springboot.listener.original.CustomApplicationListenerEnvironmentPrepared;
import com.only.mate.springboot.listener.original.CustomApplicationListenerFailed;
import com.only.mate.springboot.listener.original.CustomApplicationListenerPrepared;
import com.only.mate.springboot.listener.original.CustomApplicationListenerStarted; @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
//使用 @EnableWebMvc 注解,需要以编程的方式指定视图文件相关配置;
//@EnableWebMvc
//使用 @EnableAutoConfiguration 注解,会读取 application.properties 或 application.yml 文件中的配置
@EnableAutoConfiguration
@ServletComponentScan//springboot启动类扫描servlet组件(过滤器)
public class Application {
public static ApplicationContext applicationContext; private static final Logger logger = LoggerFactory.getLogger(Application.class); public static void main(String[] args) {
startApplication(args);
} public static ApplicationContext startApplication(String[] args) {
if (applicationContext == null) {
logger.info(" >>> Springboot Application 开始启动...");
SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
SpringApplication application = builder.application();
application.addListeners(new CustomApplicationListenerEnvironmentPrepared());//这里注册事件监听器
application.addListeners(new CustomApplicationListenerFailed());//这里注册事件监听器
application.addListeners(new CustomApplicationListenerPrepared());//这里注册事件监听器
application.addListeners(new CustomApplicationListenerStarted());//这里注册事件监听器 applicationContext = application.run(args);
logger.info(" >>> Springboot Application 启动完成!");
}
return applicationContext;
} public static ApplicationContext getApplicationContext() {
if (applicationContext == null) {
logger.error(" >>> Error:Springboot Application ApplicationContext is Null.");
}
return applicationContext;
} }

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
//使用 @EnableWebMvc 注解,需要以编程的方式指定视图文件相关配置;
//@EnableWebMvc
//使用 @EnableAutoConfiguration 注解,会读取 application.properties 或 application.yml 文件中的配置
@EnableAutoConfiguration
@ServletComponentScan//springboot启动类扫描servlet组件(过滤器)
public class Application {
public static ApplicationContext applicationContext; private static final Logger logger = LoggerFactory.getLogger(Application.class); public static void main(String[] args) {
SpringApplication application = new SpringApplication(Application.class);
application.addListeners(new CustomApplicationListenerEnvironmentPrepared());//这里注册事件监听器
application.addListeners(new CustomApplicationListenerFailed());//这里注册事件监听器
application.addListeners(new CustomApplicationListenerPrepared());//这里注册事件监听器
application.addListeners(new CustomApplicationListenerStarted());//这里注册事件监听器
application.run(args);
}
}

注意:注册事件监听器一定要在启动之前注册。

  3、效果图

启动成功是只有三个事件被监听到的。

二、自定义事件监听

  Spring的事件遵循的流程:

  1. 自定义事件,继承ApplicationEvent(org.springframework.context.ApplicationEvent)
  2. 自定义监听,实现ApplicationListener<T>(org.springframework.context.ApplicationListener)接口,然后实现onApplicationEvent方法
  3. 使用容器触发事件

  1、自定义事件

/**
* @Description: 自定义事件
* @ClassName: CustomEvent
* @author OnlyMate
* @Date 2018年9月14日 下午3:01:58
*
*/
public class CustomEvent extends ApplicationEvent { private static final long serialVersionUID = -7058371859589691525L;
private Logger logger = LoggerFactory.getLogger(CustomEvent.class); private String msg; public CustomEvent(Object source,String msg) {
super(source);
this.msg = msg;
} /**
* 自定义监听器触发的透传打印方法
* @Title: printMsg
* @author OnlyMate
* @Date 2018年9月14日 下午3:10:45
* @param msg
*/
public void printMsg(String msg) {
logger.info("CustomEvent ==> printMsg method 自定义事件: {}", msg);
} public String getMsg() {
return msg;
} public void setMsg(String msg) {
this.msg = msg;
} }

  2、自定义事件发布

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service; /**
* 发布消息服务
* @ClassName: CustomListenerServie
* @author OnlyMate
* @Date 2018年9月14日 下午3:18:46
*
*/
@Service(value="customListenerServie")
public class CustomListenerServie {
private Logger logger = LoggerFactory.getLogger(CustomListenerServie.class); //上下文对象
@Resource
private ApplicationContext applicationContext; /**
* 发布消息
* @Title: publish
* @author OnlyMate
* @Date 2018年9月14日 下午3:18:35
* @param msg
*/
public void publish(String msg) {
//通过上下文对象发布监听
applicationContext.publishEvent(new CustomEvent(this,msg));
logger.info("CustomListenerServie ==> publish method : {}", msg);
}
}

  3、触发自定义事件

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody; import com.only.mate.springboot.listener.CustomListenerServie; @Controller
@RequestMapping(value="/listener")
public class CustomListenerController {
@Autowired
@Qualifier(value = "customListenerServie")
private CustomListenerServie customListenerServie; @ResponseBody
@RequestMapping(value="/testevent")
public String testEvent() {
customListenerServie.publish("测试监听");
return "success";
}
}

  4、自定义事件监听器并注册事件监听器

  Spring Boot进行事件监听有四种方式:

  1. 手工向ApplicationContext中添加监听器
  2. 在application.properties中配置监听器
  3. 将监听器装载入Spring容器
  4. 通过@EventListener注解实现事件监听

  a、手工向ApplicationContext中添加监听器

  事件监听器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener; /**
* 自定义监听器,监听事件为CustomEvent
* @ClassName: CustomListener
* @author OnlyMate
* @Date 2018年9月14日 下午3:13:43
*
*/
public class CustomListener implements ApplicationListener<CustomEvent>{
private Logger logger = LoggerFactory.getLogger(CustomAnnotationListener.class);
/**
* 对监听到的事件进行处理
*/
@Override
public void onApplicationEvent(CustomEvent event) {
//这里不做处理,只对消息进行透传打印,实际情况,
//可以根据项目进行逻辑进行处理
event.printMsg(event.getMsg());
logger.info("CustomListener ==> onApplicationEvent method : {}", event.getMsg());
} }
  配置
import java.util.HashSet;
import java.util.Set; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext; import com.only.mate.springboot.listener.CustomListener; @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
//使用 @EnableWebMvc 注解,需要以编程的方式指定视图文件相关配置;
//@EnableWebMvc
//使用 @EnableAutoConfiguration 注解,会读取 application.properties 或 application.yml 文件中的配置
@EnableAutoConfiguration
@ServletComponentScan//springboot启动类扫描servlet组件(过滤器)
public class Application {
public static ApplicationContext applicationContext; private static final Logger logger = LoggerFactory.getLogger(Application.class); public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
context.addApplicationListener(new CustomListener());//这里注册事件监听器
}
}

  或

import java.util.HashSet;
import java.util.Set; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ApplicationContext; import com.only.mate.springboot.listener.CustomListener; @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
//使用 @EnableWebMvc 注解,需要以编程的方式指定视图文件相关配置;
//@EnableWebMvc
//使用 @EnableAutoConfiguration 注解,会读取 application.properties 或 application.yml 文件中的配置
@EnableAutoConfiguration
@ServletComponentScan//springboot启动类扫描servlet组件(过滤器)
public class Application {
public static ApplicationContext applicationContext; private static final Logger logger = LoggerFactory.getLogger(Application.class); public static void main(String[] args) {
startApplication(args);
} public static ApplicationContext startApplication(String[] args) {
if (applicationContext == null) {
logger.info(" >>> Springboot Application 开始启动...");
SpringApplicationBuilder builder = new SpringApplicationBuilder(Application.class);
SpringApplication application = builder.application();
application.addListeners(new CustomListener());//这里注册事件监听器
applicationContext = application.run(args);
logger.info(" >>> Springboot Application 启动完成!");
}
return applicationContext;
} public static ApplicationContext getApplicationContext() {
if (applicationContext == null) {
logger.error(" >>> Error:Springboot Application ApplicationContext is Null.");
}
return applicationContext;
} }
  效果图

  访问http://localhost:8088/springboot/listener/testevent

  b、在application.properties中配置监听器

  事件监听器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener; /**
* 自定义监听器,监听事件为CustomEvent
* @ClassName: CustomListener
* @author OnlyMate
* @Date 2018年9月14日 下午3:13:43
*
*/
public class CustomListener implements ApplicationListener<CustomEvent>{
private Logger logger = LoggerFactory.getLogger(CustomAnnotationListener.class);
/**
* 对监听到的事件进行处理
*/
@Override
public void onApplicationEvent(CustomEvent event) {
//这里不做处理,只对消息进行透传打印,实际情况,
//可以根据项目进行逻辑进行处理
event.printMsg(event.getMsg());
logger.info("CustomListener ==> onApplicationEvent method : {}", event.getMsg());
} }
  配置

  在application.properties中配置监听

context.listener.classes=com.only.mate.springboot.listener.CustomListener
  效果图

  访问http://localhost:8088/springboot/listener/testevent

  c、将监听器装载入Spring容器

  事件监听器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component; /**
* 自定义监听器,监听事件为CustomEvent
* @ClassName: CustomListener
* @author OnlyMate
* @Date 2018年9月14日 下午3:13:43
*
*/
@Component
public class CustomListener implements ApplicationListener<CustomEvent>{
private Logger logger = LoggerFactory.getLogger(CustomAnnotationListener.class);
/**
* 对监听到的事件进行处理
*/
@Override
public void onApplicationEvent(CustomEvent event) {
//这里不做处理,只对消息进行透传打印,实际情况,
//可以根据项目进行逻辑进行处理
event.printMsg(event.getMsg());
logger.info("CustomListener ==> onApplicationEvent method : {}", event.getMsg());
} }

这里用@Component注解将事件监听器注册到Spring容器中

  效果图

  访问http://localhost:8088/springboot/listener/testevent

  d、通过@EventListener注解实现事件监听

  事件监听器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component; @Component
public class CustomAnnotationListener {
private Logger logger = LoggerFactory.getLogger(CustomAnnotationListener.class); @EventListener
public void listener1(CustomEvent event) {
event.printMsg(event.getMsg());
logger.info("CustomAnnotationListener ==> listener1 method : {}", event.getMsg());
} @EventListener
public void listener2(CustomEvent event) {
event.printMsg(event.getMsg());
logger.info("CustomAnnotationListener ==> listener2 method : {}", event.getMsg());
}
}
  效果图

  访问http://localhost:8088/springboot/listener/testevent


  如果是使用配置文件来注册的话,ApplicationStartedEvent这种事件是监听不到的,因为配置文件加载代表着Spring Boot已经启动,不过其他两种事件已经足够给项目上使用了。

Spring Boot实践——事件监听的更多相关文章

  1. spring源码-事件&监听3.6

    一.spring中的发布与监听模式,是我们最常用的一种观察者模式.spring在其中做了很多优化,目的就是让用户更好的使用事件与监听的过程. 二.常用的事件与监听中涉及到的接口和类为:Applicat ...

  2. Spring Boot实现一个监听用户请求的拦截器

    项目中需要监听用户具体的请求操作,便通过一个拦截器来监听,并继续相应的日志记录 项目构建与Spring Boot,Spring Boot实现一个拦截器很容易. Spring Boot的核心启动类继承W ...

  3. rabbitMq与spring boot搭配实现监听

    在我前面有一篇博客说到了rabbitMq实现与zk类似的watch功能,但是那一篇博客没有代码实例,后面自己补了一个demo,便于理解.demo中主要利用spring boot的配置方式, 一.消费者 ...

  4. Spring boot设置启动监听端口

    一.通过配置 修改application.properties 在属性文件中添加server.port=8000 二.直接看代码: @Controller @EnableAutoConfigurati ...

  5. Spring中的事件监听实现

    在spring中我们可以自定义事件,并且可以使用ApplicationContext类型对象(就是spring容器container)来发布这个事件 事件发布之后,所有的ApplicaitonList ...

  6. spring boot实战(第二篇)事件监听

    http://blog.csdn.net/liaokailin/article/details/48186331 前言 spring boot在启动过程中增加事件监听机制,为用户功能拓展提供极大的便利 ...

  7. Spring之事件监听(观察者模型)

    目录 Spring事件监听 一.事件监听案例 1.事件类 2.事件监听类 3.事件发布者 4.配置文件中注册 5.测试 二.Spring中事件监听分析 1. Spring中事件监听的结构 2. 核心角 ...

  8. (转)spring boot实战(第三篇)事件监听源码分析

    原文:http://blog.csdn.net/liaokailin/article/details/48194777 监听源码分析 首先是我们自定义的main方法: package com.lkl. ...

  9. 009-Spring Boot 事件监听、监听器配置与方式、spring、Spring boot内置事件

    一.概念 1.事件监听的流程 步骤一.自定义事件,一般是继承ApplicationEvent抽象类 步骤二.定义事件监听器,一般是实现ApplicationListener接口 步骤三.启动时,需要将 ...

随机推荐

  1. The web application you are attempting to access on this web server is currently unavailable.......

    今天去服务器安装了个.net 4.0 framework(原本有1.0和2.0的),配置好站点后,选择版本为4.0,访问出错,错误代码如下 Server Application Unavailable ...

  2. 快速切题 poj 2996 Help Me with the Game 棋盘 模拟 暴力 难度:0

    Help Me with the Game Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3510   Accepted:  ...

  3. 编译安装zabbix3.2.5

    1. 配置lnmp环境 首先配置Nginx+mysql+php-fpm的系统环境,具体配置见另一篇文章 2. 编译安装zabbix 2.1 下载并解压zabbix 可以到zabbix官网下载zabbi ...

  4. 【Ubuntu14】Nginx+PHP5+Mysql记录

    这次因为工作原因,需要在Linux下进行开发.推荐的环境是Ubuntu14+Nginx+PHP+Mysql.环境搭建好之后,装上GIT,装上IDE,觉得Mysql命令界面麻烦又装了个Navicat.总 ...

  5. Entity Framework 入门

    Entity Framework的全称是ADO.NET Entity Framework,是微软开发的基于ADO.NET的ORM(Object/Relational Mapping)框架. Entit ...

  6. js 验证手机号码

    js 验证手机号码 //验证手机号        function isMobel(value) {           if (/^1[3-8]+\d{9}$/g.test(value)) {    ...

  7. Nodejs中npm install 命令的问题

    在使用nodejs的npm包管理工具中碰到过许多个坑,在网上查了很久才解决,现在加以总结. 两种安装方式(本地安装,全局安装) 1.全局安装(npm install -g moduleName/npm ...

  8. Oracle XE自带数据库创建的过程

    Oracle XE自带数据库如何创建的?XE.sql脚本定义实例究竟是怎样的?阅读下文,您可以找到这些问题的答案. Oracle XE自带数据库是如何创建的呢?这是很多人都提到过的问题,下面就为您详细 ...

  9. java并发之原子性、可见性、有序性

    链接:https://blog.csdn.net/gongpulin/article/details/51211616

  10. myeclipse越来越卡了怎么回事啊?

    去掉拼写检查:windows->preferences->General->Editors->Text Editors->Spelling 将“Enable spell ...