我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解Java事件编程的使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解Java事件编程的使用

Java事件编程

当前在线网店很多,很涉及商品管理和销售的问题,比如:

一,在商品库存管理的商品增加时,我们主要业务时编辑保持商品信息,

同时因商品增加而附带有一些“非主要业务”,如:

1,应商品的库存数量等更新,
2,热销产品的推广处理等

二,在商品产生订单时,我们的主要业务(对买家而言)是建立订单业务,

同时因产生订单而附带有一些不是买家关心的“非主要业务”,如:

1,库存和已售数量的更新
2,发货的准备处理事宜
3,物流的处理事宜

非主要业务我们可以让程序使用多线程异步执行,这样主要业务和非主要业务就完全解耦,
主要业务可以快速完成响应,非主要业务多线程异步执行,提高程序的吞吐量即高处理能力;
同时使用自定义的线程池,有比较好的把控;

下面我们就根据上面的场景需求编写一个例子,看看在Springboot中如何Java的事件编程,
对比一下常规逻辑的编程,和采用Java事件编程的差异。


//常规逻辑的编程
@GetMapping(value="/add")  
@ResponseBody
public String addProduct(Product product) {
	
	
	//增加产品
	
	//应商品的库存数量等更新
	
	//是否为热销产品的推广处理
	
	//其它处理
	
	return "产品增加完成";
}

主要业务是增加产品信息,但是可能会因产品库存或热销产品等其它问题处理而收到影响,
耦合性比较强,如果以后还有其它需求又需要改动程序,问题暴露出来了;

同样,下单也是一样问题,主要业务是买家下单时建立订单,


//常规逻辑的编程
@GetMapping(value="/createOrder")  
@ResponseBody
public String createProductOrder(ProductOrder productOrder) {
	
	
	//收集产品订单信息,保持建立订单
	
	//库存和已售数量的更新
	
	//订单备货处理
	
	//物流处理
	
	return "产品订单建立完成";
}

对买家来说,主要业务是产品下单,后续的库存和已售数量的更新,备货处理,物流处理等不是买家关心的,但是可能会因这些问题处理而受到影响,可能下单失败,耦合性比较强,如果以后还有其它需求又需要改动程序,同样问题暴露出来了;

那怎么建立主次分明的处理逻辑呢,这里用Java事件编程就很好处理这些问题,主次分明,完全解耦,程序改动比较小,程序吞吐量也强,
相关注释在程序非常清楚,所以主要看代码吧;

三,使用Java事件编程,Springboot例子

1,项目结构如下图: 

2,自定义异步执行使用的线程池,参考如下代码:


package com.shenzhennba.pro06.eventSource.asyncConfig;
 
import java.io.Serializable;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 

@Configuration
public class AsyncThreadPoolConfig implements Serializable {
 
	private static final long serialVersionUID = 20210606010060L;
	
	private static final int MAX_POOL_SIZE = 100;
    private static final int CORE_POOL_SIZE = 20;
    private static final String THREAD_NAME_PREFIX = "async_task_";
	
    //创建线程池,并指定实例名称
    @Bean("asyncTaskExecutor")
    public AsyncTaskExecutor asyncTaskExecutor() {
		ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
		asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
		asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
		asyncTaskExecutor.setThreadNamePrefix(THREAD_NAME_PREFIX);
		asyncTaskExecutor.initialize();
		return asyncTaskExecutor;
	}
    
}

3,定义业务相关需要的实体或model,参考如下代码: 


package com.shenzhennba.pro06.eventSource.model;
 
import java.io.Serializable;
 
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
 

public class Product implements Serializable {
 
	private static final long serialVersionUID = 20210606010010L;
	private String categoryCode;//商品类别代码
	private String productName;	//商品名称
	private String productCode;	//商品代码
	private Double price;		//商品单价
	private Long addNum;		//增加数量
	private Long isHotSell=0L;	//是否促销,0=不是,1=是
	private String createTime;	//商品入库时间
	
	public Product() {
		super();
	}
 
	//getter / setter 省略...
	
	@Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }
	
}

package com.shenzhennba.pro06.eventSource.model;
 
import java.io.Serializable;
 
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
 

public class ProductNumber implements Serializable {
	private static final long serialVersionUID = 20210606010020L;	
	private String productCode;	//商品代码
	private Long storageNum;	//商品库存
	private Long soldNum;		//已收数量
	private Long scoreNum;		//单个购买赠送积分数
	
	public ProductNumber() {
		super();
	}
 
	// getter / setter 省略...
	
	@Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }
}

package com.shenzhennba.pro06.eventSource.model;
 
import java.io.Serializable;
import java.util.Date;
 
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
 

public class ProductOrder implements Serializable {
	
	private static final long serialVersionUID = 20210606010030L;
	private String orderCode;	//订单代码
	private String productName;	//商品名称
	private String productCode;	//商品代码
	private Double price;		//商品单价
	private String createTime;	//下单时间
	private Long scoreNum;		//购买赠送积分数
	private Long buyNum;		//订单购买数量
	private Integer isPrepared = 0;//发货准备状态,默认0=未准备好,1=已准备好
	private Integer isSendOut = 0;//是否已发货,默认0=未发,1=已发
	private String warehouseCode ;//发货仓库代码
	private String senderCode ;	//物流处理商家代码
	private Date planSendTime ;	//计划发货时间
	private Date recieveTime ;	//收货时间
	private String recieveAddress;//收货地址
	
	public ProductOrder() {
		super();
	}
 
	// getter / setter 省略...
	
	@Override
    public String toString() {
        return ReflectionToStringBuilder.toString(this);
    }

4,定义业务的相关Java事件源,主要是编写继承 
org.springframework.context.ApplicationEvent 的类对象,
以及定义各事件相关的对象
,比如,商品对象,或订单对象,事件源的目的是存储事件相关的目标信息,参考如下代码:


package com.shenzhennba.pro06.eventSource.eventSource;
 
import java.io.Serializable;
 
import org.springframework.context.ApplicationEvent;
 
import com.shenzhennba.pro06.eventSource.model.Product;
 

public class ProductEventSource 
	extends ApplicationEvent implements Serializable {
 
	private static final long serialVersionUID = 20210606010040L;
	
	//目的是用于存储事件的目标信息,即添加的商品对象
	private Product product;
	
	public ProductEventSource(Product source) {
		super(source);
		this.product = source;
	}
 
	public Product getProduct() {
		return product;
	}
 
	public void setProduct(Product product) {
		this.product = product;
	}
	
}

package com.shenzhennba.pro06.eventSource.eventSource;
 
import java.io.Serializable;
 
import org.springframework.context.ApplicationEvent;
 
import com.shenzhennba.pro06.eventSource.model.ProductOrder;
 

public class ProductOrderEventSource 
	extends ApplicationEvent implements Serializable{
 
	private static final long serialVersionUID = 20210606010050L;
	
	//目的是用于存储事件的目标信息,即建立的商品订单对象
	private ProductOrder productOrder;
			
	public ProductOrderEventSource(ProductOrder source) {
		super(source);
		this.productOrder = source;
	}
	
	public ProductOrder getProductOrder() {
		return productOrder;
	}
	
	public void setProductOrder(ProductOrder productOrder) {
		this.productOrder = productOrder;
	}	
	
}

5,定义各种监听器和相关业务处理逻辑,并将其纳入SpringIOC容器管理
监听类方法加注解 @EventListener 使之变为一个监听器,加注解@Async("asyncTaskExecutor") 指定监听器异步执行,同时指定异步执行使用的线程池,加注解  @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
指定监听器事务的阶段, 一般为业务数据入库之后,再异步执行方法;加注解 @Order(1) 指定同一事件有多个监听器时执行顺序,值越小,执行顺序优先,类前加 @Component 注解,把各监听器交给SpringIOC容器管理,参考如下代码:


package com.shenzhennba.pro06.eventSource.listener;
 
import java.io.Serializable;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
 
import com.shenzhennba.pro06.eventSource.eventSource.ProductEventSource;
import com.shenzhennba.pro06.eventSource.eventSource.ProductOrderEventSource;
import com.shenzhennba.pro06.eventSource.model.ProductOrder;
 

 
@Component
public class EventListeners implements Serializable {
	
	private static Logger logger = LoggerFactory.getLogger(EventListeners.class);
	
	private static final long serialVersionUID = 20210606010070L;
 
	//指定异步执行监听器,同时使用的自定义的异步线程池
	@Async("asyncTaskExecutor")
	//指定监听事务的阶段,多数情况下的业务操作会涉及数据库事务,确保主业务的数据入库后,再进行本方法的异步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定义本方法为一个监听器,处理因增加产品而引发的事件中有关产品库存等数量相关信息
	@EventListener
	//指定当同一个事件有多个监听器时执行顺序,值越小,执行顺序优先
	@Order(1)
	public void updateProductReferNumListener(ProductEventSource pes) {
		if (null == pes || null == pes.getProduct()) {
			return;
		}
		logger.info("");
		logger.info("产品增加事件监听器 1, 事件关联信息:{}", pes.getProduct());
		logger.info("");
		// TODO 有关产品数量的库存等更新操作
	}
	
	
	//指定异步执行监听器,同时使用的自定义的异步线程池
	@Async("asyncTaskExecutor")
	//指定监听事务的阶段,多数情况下的业务操作会涉及数据库事务,确保主业务的数据入库后,再进行本方法的异步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定义本方法为一个监听器,处理因增加产品而引发的事件中有关热销产品的相关促销事宜
	@EventListener
	//指定当同一个事件有多个监听器时执行顺序,值越小,执行顺序优先
	@Order(5)
	public void handleHotSellProductListener(ProductEventSource pes) {
		if (null == pes || null == pes.getProduct()) {
			return;
		}
		logger.info("");
		logger.info("产品增加事件监听器 2, 事件关联信息:{}", pes.getProduct());
		logger.info("");
		if (null == pes.getProduct()) {
			return;
		}
		if (1 != pes.getProduct().getIsHotSell().intValue()) {
			logger.info("产品增加事件监听器 2, 非热销产品");
			return;
		}
		// TODO 有关热销产品的相关促销事宜的处理
	}
	
	
	//指定异步执行监听器,同时使用的自定义的异步线程池
	@Async("asyncTaskExecutor")
	//指定监听事务的阶段,多数情况下的业务操作会涉及数据库事务,确保主业务的数据入库后,再进行本方法的异步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定义本方法为一个监听器,处理因产品产生订单而引发的事件中有关产品库存和已售数量相关信息
	@EventListener
	//指定当同一个事件有多个监听器时执行顺序,值越小,执行顺序优先
	@Order(1)
	public void updateProductReferNumListener(ProductOrderEventSource poes) {
		if (null == poes || null == poes.getProductOrder()) {
			return;
		}
		logger.info("");
		logger.info("产品产生订单事件监听器 1, 事件关联信息:{}", poes.getProductOrder());
		logger.info("");
		// TODO 有关产品数量的库存和已售数量更新操作
	}
	
	
	//指定异步执行监听器,同时使用的自定义的异步线程池
	@Async("asyncTaskExecutor")
	//指定监听事务的阶段,多数情况下的业务操作会涉及数据库事务,确保主业务的数据入库后,再进行本方法的异步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定义本方法为一个监听器,处理因产品产生订单而引发的事件中有关产品发货的相关准备和处理事宜
	@EventListener
	//指定当同一个事件有多个监听器时执行顺序,值越小,执行顺序优先
	@Order(5)
	public void prepareSendProductListener(ProductOrderEventSource poes) {
		if (null == poes || null == poes.getProductOrder()) {
			return;
		}
		ProductOrder proOrder = poes.getProductOrder();
		logger.info("");
		logger.info("产品产生订单事件监听器 2, 事件关联信息:{}", proOrder);
		logger.info("");
		if (null != proOrder.getIsSendOut() && 
				1 == proOrder.getIsSendOut()) {
			logger.info("产品产生订单事件监听器 2, 订单已经发货,不用再处理");
			return;
		}
		if (null != proOrder.getIsPrepared() && 
				1 == proOrder.getIsPrepared()) {
			logger.info("产品产生订单事件监听器 2, 订单发货准备已经完成,不用再处理");
			return;
		}
		// TODO 有关产品订单发货的事宜
	}
	
		
	//指定异步执行监听器,同时使用的自定义的异步线程池
	@Async("asyncTaskExecutor")
	//指定监听事务的阶段,多数情况下的业务操作会涉及数据库事务,确保主业务的数据入库后,再进行本方法的异步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定义本方法为一个监听器,处理因产品产生订单而引发的事件中有关产品发货的物流事宜
	@EventListener
	//指定当同一个事件有多个监听器时执行顺序,值越小,执行顺序优先
	@Order(10)
	public void sendProductListener(ProductOrderEventSource poes) {
		if (null == poes || null == poes.getProductOrder()) {
			return;
		}
		ProductOrder proOrder = poes.getProductOrder();
		logger.info("");
		logger.info("产品产生订单事件监听器 3, 事件关联信息:{}", poes.getProductOrder());
		logger.info("");
		if (null != proOrder.getIsSendOut() && 
				1 == proOrder.getIsSendOut()) {
			logger.info("产品产生订单事件监听器 3, 订单已经发货,不用再处理");
			return;
		}
		if (null != proOrder.getIsPrepared() && 
				0 == proOrder.getIsPrepared().intValue()) {
			logger.info("产品产生订单事件监听器 3, 订单发货准备还未完成,先等备好货,再处理物流事宜");
		}
		// TODO 有关产品订单的物流事宜
	}	
	
}

6,定义业务接口,参考如下代码:


package com.shenzhennba.pro06.eventSource.service;
 
import java.io.Serializable;
 
import com.shenzhennba.pro06.eventSource.model.Product;
 

public interface ProductService extends Serializable {
	
	
	Integer addProduct(Product product);
	
	
	Product getProduct(String productCode);
	
}

package com.shenzhennba.pro06.eventSource.service;
 
import java.io.Serializable;
 
import com.shenzhennba.pro06.eventSource.model.Product;
import com.shenzhennba.pro06.eventSource.model.ProductOrder;
 

public interface ProductOrderService extends Serializable {
 
	
	Integer createProductOrder(ProductOrder productOrder);
	
	
	Product getProductOrder(String productOrderCode);
	
}

7,实现所定义的业务接口,参考如下代码:


package com.shenzhennba.pro06.eventSource.service.impl;
 
import org.springframework.stereotype.Service;
 
import com.shenzhennba.pro06.eventSource.model.Product;
import com.shenzhennba.pro06.eventSource.service.ProductService;
 

 
@Service
public class ProductServiceImpl implements ProductService {
 
	private static final long serialVersionUID = 20210606010090L;
	
	
	@Override
	public Integer addProduct(Product product) {
		// TODO more biz handle here
		return null;
	}
 
	
	@Override
	public Product getProduct(String productCode) {
		// TODO more biz handle here
		return null;
	}
 
}

package com.shenzhennba.pro06.eventSource.service.impl;
 
import org.springframework.stereotype.Service;
 
import com.shenzhennba.pro06.eventSource.model.Product;
import com.shenzhennba.pro06.eventSource.model.ProductOrder;
import com.shenzhennba.pro06.eventSource.service.ProductOrderService;
 

@Service
public class ProductOrderServiceImpl implements ProductOrderService {
 
	private static final long serialVersionUID = 20210606010100L;
	
	
	@Override
	public Integer createProductOrder(ProductOrder productOrder) {
		// TODO more biz handle here
		return null;
	}
 
	
	@Override
	public Product getProductOrder(String productOrderCode) {
		// TODO more biz handle here
		return null;
	}
}

8,在对外API(即controller层)接口中处理业务,同时使用 org.springframework.context.ApplicationEventPublisher 
实例发布相应的Java事件
,参考如下代码:


package com.shenzhennba.pro06.eventSource.controller;
 
import java.io.Serializable;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.shenzhennba.pro06.eventSource.eventSource.ProductEventSource;
import com.shenzhennba.pro06.eventSource.listener.EventListeners;
import com.shenzhennba.pro06.eventSource.model.Product;
import com.shenzhennba.pro06.eventSource.service.ProductService;
 

 
@Controller
@RequestMapping("/product")
public class ProductController implements Serializable {
 
	private static Logger logger = LoggerFactory.getLogger(EventListeners.class);
	private static final long serialVersionUID = 20210606010080L;
	
	//Spring的事件发布器
	@Autowired
	private ApplicationEventPublisher appEventPublisher;
	
	@Autowired
	private ProductService productService;
	
	@GetMapping(value="/add")  
	@ResponseBody
	public String addProduct(Product product) {
		logger.info("controller ProductController.addProduct(), add product");
		
		//主要业务,增加产品
		productService.addProduct(product);
		
		//?categoryCode=c01&productName=productName001&productCode=pc001&price=20.5&addNum=2&isHotSell=1
		//因增加产品而发布与其相关的事件,处理与之相关的非主要业务,
		//首先执行EventListeners.updateProductReferNumListener()监听器,处理相关业务
		//其次执行EventListeners.handleHotSellProductListener()监听器,处理相关业务
		//应用Spring事件,可以让非主要业务和主要业务解耦,使用异步处理非主要业务,让程序吞吐量即处理能力更强
		appEventPublisher.publishEvent(new ProductEventSource(product));
		
		return "产品增加完成";
	}
}

package com.shenzhennba.pro06.eventSource.controller;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
 
import com.shenzhennba.pro06.eventSource.eventSource.ProductOrderEventSource;
import com.shenzhennba.pro06.eventSource.listener.EventListeners;
import com.shenzhennba.pro06.eventSource.model.ProductOrder;
import com.shenzhennba.pro06.eventSource.service.ProductOrderService;
 

@Controller
@RequestMapping("/productOrder")
public class ProductOrderController {
 
	private static Logger logger = LoggerFactory.getLogger(EventListeners.class);
	private static final long serialVersionUID = 20210606010080L;
	
	//Spring的事件发布器
	@Autowired
	private ApplicationEventPublisher appEventPublisher;
	
	@Autowired
	private ProductOrderService productOrderService;
	
	@GetMapping(value="/createOrder")  
	@ResponseBody
	public String createProductOrder(ProductOrder productOrder) {
		logger.info("controller ProductOrderController.createProductOrder(), create product order");
		
		//主要业务,增加产品
		productOrderService.createProductOrder(productOrder);
		
		//?productCode=pc001&productName=productName001&price=20.5&buyNum=3&
		//scoreNum=0&warehouseCode=house01&recieveAddress=add001
		//因增加产品而发布与其相关的事件,处理与之相关的非主要业务,
		//首先执行EventListeners.updateProductReferNumListener()监听器,处理相关业务
		//其次执行EventListeners.prepareSendProductListener()监听器,处理相关业务
		//再次执行EventListeners.sendProductListener()监听器,处理相关业务
		//应用Spring事件,可以让非主要业务和主要业务解耦,使用异步处理非主要业务,让程序吞吐量即处理能力更强
		appEventPublisher.publishEvent(new ProductOrderEventSource(productOrder));
		
		return "产品订单建立完成";
	}
}

9,在启动类中启用异步处理功能,参考如下代码:


package com.shenzhennba.pro06.eventSource;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync;
 
//启动异步处理功能
@EnableAsync 
//启动springboot但不用排除DB功能
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class EventSourceApp {
	
	private static Logger logger = LoggerFactory.getLogger(EventSourceApp.class);
	
	public static void main(String[] args) {
		SpringApplication.run(EventSourceApp.class, args);
		
		logger.info("");
		logger.info("----------- Server is running... -----------");
		logger.info("");
	}
	
}

10,工程配置文件,参考如下代码:


spring.application.name=eventSourceApp01
 
server.port=8080

11,启动工程,模拟增加一个商品,相关截图如下,可见商品增加事件已经触发,

http://localhost:8080/product/add?categoryCode=c01&productName=productName001&productCode=pc001&price=20.5&addNum=2&isHotSell=1

12,启动工程,模拟建立一个订单,相关截图如下,可见订单相关事件已经触发

http://localhost:8080/productOrder/createOrder?productCode=pc001&productName=productName001&price=20.5&buyNum=3&scoreNum=0&wa
rehouseCode=house01&recieveAddress=add001

13,工程 pom.xml 文件,参见如下代码:


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
	https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.0</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.shenzhennba.pro06</groupId>
	<artifactId>eventSource</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>eventSource</name>
	<description>Demo event source</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-rest</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
 
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<!-- apache的依赖 -->
		<dependency>
		    <groupId>commons-lang</groupId>
		    <artifactId>commons-lang</artifactId>
		    <version>2.6</version>
		</dependency>		
	</dependencies>
 
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>				
			</plugin>
		</plugins>
	</build>
 
</project>

后记

Java的事件编程可以应用到很多的地方,合理应用可以使代码主次业务分清,业务解耦,提高程序吞吐量,但需要开发人员掌握更多的知识,只要学习应该不是很难,习惯一种编程逻辑多一种开发思路,欢迎拍砖讨论...

到此这篇关于详解Java事件编程的使用的文章就介绍到这了,更多相关Java事件编程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解Java事件编程的使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Node.js中的事件驱动编程详解

在传统程编程模里,I/O操作就像一个普通的本地函数调用:在函数执行完之前程序被堵塞,无法继续运行。堵塞I/O起源于早先的时间片模型,这种模型下每个进程就像一个独立的人,目的是将每个人区分开,而且每个人在同一时刻通常只能做一件事,必须等待前面
2022-06-04

Android编程输入事件流程详解

本文实例讲述了Android编程输入事件流程。分享给大家供大家参考,具体如下: EventHub对输入设备进行了封装。输入设备驱动程序对用户空间应用程序提供一些设备文件,这些设备文件放在/dev/input里面。 EventHub扫描/de
2022-06-06

js oncontextmenu事件使用详解

oncontextmenu事件是在用户右击页面上的元素时触发的JavaScript事件。它通常用于阻止默认的右键菜单弹出,并自定义一个自定义的右键菜单。使用oncontextmenu事件的语法如下:```javascriptelement.
2023-08-08

node中socket.io的事件使用详解

socket.io类库不但可以相互发送消息,而且还可以通过socket端口对象的emit方法互相发送事件. emit在之前的事件上说过现在一句话带过:emit是用来手动触发事件的.socket.emit(event,data,functio
2022-06-04

Java语言中Swing组件编程详解

这篇文章主要为大家介绍了Java语言中Swing组件编程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

详解Vue3中Watch监听事件的使用

这篇文章主要为大家详细介绍了Vue3中Watch监听事件的使用的相关资料,文中的示例代码讲解详细,对我们学习Vue3有一定的帮助,需要的可以参考一下
2023-02-10

Android编程之滑动按钮事件实例详解

本文实例讲述了Android滑动按钮事件。分享给大家供大家参考,具体如下: 今天纪录一下滑动按钮功能。。 首先效果图:然后是分别建立三个文件,第一个是main.class,第二个是SlipButton.class,第三个是 onchange
2022-06-06

详解Laravel模型事件和模型事件在Trait中的使用

这篇文章主要为大家介绍了详解Laravel模型事件和模型事件在Trait中的使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-07

Flutter事件监听与EventBus事件的应用详解

EventBus的核心是基于Streams。它允许侦听器订阅事件并允许发布者触发事件,使得不同组件的数据不需要一层层传递,可以直接通过EventBus实现跨组件通讯
2023-05-15

Java网络编程基础用法详解

网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来,本文将带大家详细了解Java的网络编程,文中有相关的代码示例,需要的朋友可以参考下
2023-05-19

详解Python编程中time模块的使用

一、简介 time模块提供各种操作时间的函数 说明:一般有两种表示时间的方式: 第一种是时间戳的方式(相对于1970.1.1 00:00:00以秒计算的偏移量),时间戳是惟一的 第二种以数组的形式表示即(struct_time),共有九个元
2022-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录