文章详情

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

请输入下面的图形验证码

提交验证

短信预约提醒成功

详解Java事件编程的使用

2024-04-02 19:55

关注

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

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯