詳解Java事件編程的使用
Java事件編程
當前在線網店很多,很涉及商品管理和銷售的問題,比如:
一,在商品庫存管理的商品增加時,我們主要業(yè)務時編輯保持商品信息,
同時因商品增加而附帶有一些“非主要業(yè)務”,如:
1,應商品的庫存數量等更新,
2,熱銷產品的推廣處理等
二,在商品產生訂單時,我們的主要業(yè)務(對買家而言)是建立訂單業(yè)務,
同時因產生訂單而附帶有一些不是買家關心的“非主要業(yè)務”,如:
1,庫存和已售數量的更新
2,發(fā)貨的準備處理事宜
3,物流的處理事宜
非主要業(yè)務我們可以讓程序使用多線程異步執(zhí)行,這樣主要業(yè)務和非主要業(yè)務就完全解耦,
主要業(yè)務可以快速完成響應,非主要業(yè)務多線程異步執(zhí)行,提高程序的吞吐量即高處理能力;
同時使用自定義的線程池,有比較好的把控;
下面我們就根據上面的場景需求編寫一個例子,看看在Springboot中如何Java的事件編程,
對比一下常規(guī)邏輯的編程,和采用Java事件編程的差異。
//常規(guī)邏輯的編程 @GetMapping(value="/add") @ResponseBody public String addProduct(Product product) { //增加產品 //應商品的庫存數量等更新 //是否為熱銷產品的推廣處理 //其它處理 return "產品增加完成"; }
主要業(yè)務是增加產品信息,但是可能會因產品庫存或熱銷產品等其它問題處理而收到影響,
耦合性比較強,如果以后還有其它需求又需要改動程序,問題暴露出來了;
同樣,下單也是一樣問題,主要業(yè)務是買家下單時建立訂單,
//常規(guī)邏輯的編程 @GetMapping(value="/createOrder") @ResponseBody public String createProductOrder(ProductOrder productOrder) { //收集產品訂單信息,保持建立訂單 //庫存和已售數量的更新 //訂單備貨處理 //物流處理 return "產品訂單建立完成"; }
對買家來說,主要業(yè)務是產品下單,后續(xù)的庫存和已售數量的更新,備貨處理,物流處理等不是買家關心的,但是可能會因這些問題處理而受到影響,可能下單失敗,耦合性比較強,如果以后還有其它需求又需要改動程序,同樣問題暴露出來了;
那怎么建立主次分明的處理邏輯呢,這里用Java事件編程就很好處理這些問題,主次分明,完全解耦,程序改動比較小,程序吞吐量也強,
相關注釋在程序非常清楚,所以主要看代碼吧;
三,使用Java事件編程,Springboot例子,
1,項目結構如下圖:
2,自定義異步執(zhí)行使用的線程池,參考如下代碼:
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; /** * 配置異步任務線程池,然后注入springIOC容器,提供異步任務使用; * @author shenzhenNBA * @since 2021/06/14 */ @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_"; //創(chuàng)建線程池,并指定實例名稱 @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,定義業(yè)務相關需要的實體或model,參考如下代碼:
package com.shenzhennba.pro06.eventSource.model; import java.io.Serializable; import org.apache.commons.lang.builder.ReflectionToStringBuilder; /** * 商品實體類 * @author shenzhenNBA * @since 2021/06/14 */ 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; /** * 商品的數量和積分相關實體類 * @author shenzhenNBA * @since 2021/06/14 */ 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; /** * 商品訂單實體類 * @author shenzhenNBA * @since 2021/06/14 */ 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;//發(fā)貨準備狀態(tài),默認0=未準備好,1=已準備好 private Integer isSendOut = 0;//是否已發(fā)貨,默認0=未發(fā),1=已發(fā) private String warehouseCode ;//發(fā)貨倉庫代碼 private String senderCode ; //物流處理商家代碼 private Date planSendTime ; //計劃發(fā)貨時間 private Date recieveTime ; //收貨時間 private String recieveAddress;//收貨地址 public ProductOrder() { super(); } // getter / setter 省略... @Override public String toString() { return ReflectionToStringBuilder.toString(this); }
4,定義業(yè)務的相關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; /** * 商品添加事件源的定義,目的是用于存儲事件的目標信息,即添加的商品對象; * 注意:是繼承ApplicationEvent的普通Bean對象 * @author shenzhenNBA * @since 2021/06/14 */ 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; /** * 商品訂單建立事件源的定義,目的是用于存儲事件的目標信息,即建立的商品訂單對象; * 注意:是繼承ApplicationEvent的普通Bean對象 * @author shenzhenNBA * @since 2021/06/14 */ 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,定義各種監(jiān)聽器和相關業(yè)務處理邏輯,并將其納入SpringIOC容器管理,
監(jiān)聽類方法加注解 @EventListener 使之變?yōu)橐粋€監(jiān)聽器,加注解@Async("asyncTaskExecutor") 指定監(jiān)聽器異步執(zhí)行,同時指定異步執(zhí)行使用的線程池,加注解 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
指定監(jiān)聽器事務的階段, 一般為業(yè)務數據入庫之后,再異步執(zhí)行方法;加注解 @Order(1) 指定同一事件有多個監(jiān)聽器時執(zhí)行順序,值越小,執(zhí)行順序優(yōu)先,類前加 @Component 注解,把各監(jiān)聽器交給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; /** * 定義各種事件監(jiān)聽器和其各自的業(yè)務處理邏輯, * 然后注入springIOC容器,并監(jiān)聽相應的事件,只要觸發(fā)相應事件則用對應監(jiān)聽器處理; * 注意:各種監(jiān)聽器還是由spring容器管理 * @author shenzhenNBA * @since 2021/06/14 */ @Component public class EventListeners implements Serializable { private static Logger logger = LoggerFactory.getLogger(EventListeners.class); private static final long serialVersionUID = 20210606010070L; //指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池 @Async("asyncTaskExecutor") //指定監(jiān)聽事務的階段,多數情況下的業(yè)務操作會涉及數據庫事務,確保主業(yè)務的數據入庫后,再進行本方法的異步操作 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) //注解定義本方法為一個監(jiān)聽器,處理因增加產品而引發(fā)的事件中有關產品庫存等數量相關信息 @EventListener //指定當同一個事件有多個監(jiān)聽器時執(zhí)行順序,值越小,執(zhí)行順序優(yōu)先 @Order(1) public void updateProductReferNumListener(ProductEventSource pes) { if (null == pes || null == pes.getProduct()) { return; } logger.info(""); logger.info("產品增加事件監(jiān)聽器 1, 事件關聯信息:{}", pes.getProduct()); logger.info(""); // TODO 有關產品數量的庫存等更新操作 } //指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池 @Async("asyncTaskExecutor") //指定監(jiān)聽事務的階段,多數情況下的業(yè)務操作會涉及數據庫事務,確保主業(yè)務的數據入庫后,再進行本方法的異步操作 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) //注解定義本方法為一個監(jiān)聽器,處理因增加產品而引發(fā)的事件中有關熱銷產品的相關促銷事宜 @EventListener //指定當同一個事件有多個監(jiān)聽器時執(zhí)行順序,值越小,執(zhí)行順序優(yōu)先 @Order(5) public void handleHotSellProductListener(ProductEventSource pes) { if (null == pes || null == pes.getProduct()) { return; } logger.info(""); logger.info("產品增加事件監(jiān)聽器 2, 事件關聯信息:{}", pes.getProduct()); logger.info(""); if (null == pes.getProduct()) { return; } if (1 != pes.getProduct().getIsHotSell().intValue()) { logger.info("產品增加事件監(jiān)聽器 2, 非熱銷產品"); return; } // TODO 有關熱銷產品的相關促銷事宜的處理 } //指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池 @Async("asyncTaskExecutor") //指定監(jiān)聽事務的階段,多數情況下的業(yè)務操作會涉及數據庫事務,確保主業(yè)務的數據入庫后,再進行本方法的異步操作 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) //注解定義本方法為一個監(jiān)聽器,處理因產品產生訂單而引發(fā)的事件中有關產品庫存和已售數量相關信息 @EventListener //指定當同一個事件有多個監(jiān)聽器時執(zhí)行順序,值越小,執(zhí)行順序優(yōu)先 @Order(1) public void updateProductReferNumListener(ProductOrderEventSource poes) { if (null == poes || null == poes.getProductOrder()) { return; } logger.info(""); logger.info("產品產生訂單事件監(jiān)聽器 1, 事件關聯信息:{}", poes.getProductOrder()); logger.info(""); // TODO 有關產品數量的庫存和已售數量更新操作 } //指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池 @Async("asyncTaskExecutor") //指定監(jiān)聽事務的階段,多數情況下的業(yè)務操作會涉及數據庫事務,確保主業(yè)務的數據入庫后,再進行本方法的異步操作 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) //注解定義本方法為一個監(jiān)聽器,處理因產品產生訂單而引發(fā)的事件中有關產品發(fā)貨的相關準備和處理事宜 @EventListener //指定當同一個事件有多個監(jiān)聽器時執(zhí)行順序,值越小,執(zhí)行順序優(yōu)先 @Order(5) public void prepareSendProductListener(ProductOrderEventSource poes) { if (null == poes || null == poes.getProductOrder()) { return; } ProductOrder proOrder = poes.getProductOrder(); logger.info(""); logger.info("產品產生訂單事件監(jiān)聽器 2, 事件關聯信息:{}", proOrder); logger.info(""); if (null != proOrder.getIsSendOut() && 1 == proOrder.getIsSendOut()) { logger.info("產品產生訂單事件監(jiān)聽器 2, 訂單已經發(fā)貨,不用再處理"); return; } if (null != proOrder.getIsPrepared() && 1 == proOrder.getIsPrepared()) { logger.info("產品產生訂單事件監(jiān)聽器 2, 訂單發(fā)貨準備已經完成,不用再處理"); return; } // TODO 有關產品訂單發(fā)貨的事宜 } //指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池 @Async("asyncTaskExecutor") //指定監(jiān)聽事務的階段,多數情況下的業(yè)務操作會涉及數據庫事務,確保主業(yè)務的數據入庫后,再進行本方法的異步操作 @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) //注解定義本方法為一個監(jiān)聽器,處理因產品產生訂單而引發(fā)的事件中有關產品發(fā)貨的物流事宜 @EventListener //指定當同一個事件有多個監(jiān)聽器時執(zhí)行順序,值越小,執(zhí)行順序優(yōu)先 @Order(10) public void sendProductListener(ProductOrderEventSource poes) { if (null == poes || null == poes.getProductOrder()) { return; } ProductOrder proOrder = poes.getProductOrder(); logger.info(""); logger.info("產品產生訂單事件監(jiān)聽器 3, 事件關聯信息:{}", poes.getProductOrder()); logger.info(""); if (null != proOrder.getIsSendOut() && 1 == proOrder.getIsSendOut()) { logger.info("產品產生訂單事件監(jiān)聽器 3, 訂單已經發(fā)貨,不用再處理"); return; } if (null != proOrder.getIsPrepared() && 0 == proOrder.getIsPrepared().intValue()) { logger.info("產品產生訂單事件監(jiān)聽器 3, 訂單發(fā)貨準備還未完成,先等備好貨,再處理物流事宜"); } // TODO 有關產品訂單的物流事宜 } }
6,定義業(yè)務接口,參考如下代碼:
package com.shenzhennba.pro06.eventSource.service; import java.io.Serializable; import com.shenzhennba.pro06.eventSource.model.Product; /** * 商品service層接口 * @author shenzhenNBA * @since 2021/06/14 */ public interface ProductService extends Serializable { /** * 增加產品 * @author shenzhenNBA * @param product * @return */ Integer addProduct(Product product); /** * 根據產品代碼查詢產品記錄 * @author shenzhenNBA * @param product * @return */ 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; /** * 商品訂單service層接口 * @author shenzhenNBA * @since 2021/06/14 */ public interface ProductOrderService extends Serializable { /** * 建立產品訂單 * @author shenzhenNBA * @param product * @return */ Integer createProductOrder(ProductOrder productOrder); /** * 根據產品訂單代碼查詢產品訂單記錄 * @author shenzhenNBA * @param product * @return */ Product getProductOrder(String productOrderCode); }
7,實現所定義的業(yè)務接口,參考如下代碼:
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接口實現類 * @author shenzhenNBA * @since 2021/06/14 */ @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接口實現類 * @author shenzhenNBA * @since 2021/06/14 */ @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層)接口中處理業(yè)務,同時使用 org.springframework.context.ApplicationEventPublisher
實例發(fā)布相應的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; /** * 使用Java事件編程方式實現, * 產品對外API接口, * @author shenzhenNBA * @since 2021/06/14 */ @Controller @RequestMapping("/product") public class ProductController implements Serializable { private static Logger logger = LoggerFactory.getLogger(EventListeners.class); private static final long serialVersionUID = 20210606010080L; //Spring的事件發(fā)布器 @Autowired private ApplicationEventPublisher appEventPublisher; @Autowired private ProductService productService; @GetMapping(value="/add") @ResponseBody public String addProduct(Product product) { logger.info("controller ProductController.addProduct(), add product"); //主要業(yè)務,增加產品 productService.addProduct(product); //?categoryCode=c01&productName=productName001&productCode=pc001&price=20.5&addNum=2&isHotSell=1 //因增加產品而發(fā)布與其相關的事件,處理與之相關的非主要業(yè)務, //首先執(zhí)行EventListeners.updateProductReferNumListener()監(jiān)聽器,處理相關業(yè)務 //其次執(zhí)行EventListeners.handleHotSellProductListener()監(jiān)聽器,處理相關業(yè)務 //應用Spring事件,可以讓非主要業(yè)務和主要業(yè)務解耦,使用異步處理非主要業(yè)務,讓程序吞吐量即處理能力更強 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; /** * 使用Java事件編程方式實現, * 產品訂單對外API接口, * @author shenzhenNBA * @since 2021/06/14 */ @Controller @RequestMapping("/productOrder") public class ProductOrderController { private static Logger logger = LoggerFactory.getLogger(EventListeners.class); private static final long serialVersionUID = 20210606010080L; //Spring的事件發(fā)布器 @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"); //主要業(yè)務,增加產品 productOrderService.createProductOrder(productOrder); //?productCode=pc001&productName=productName001&price=20.5&buyNum=3& //scoreNum=0&warehouseCode=house01&recieveAddress=add001 //因增加產品而發(fā)布與其相關的事件,處理與之相關的非主要業(yè)務, //首先執(zhí)行EventListeners.updateProductReferNumListener()監(jiān)聽器,處理相關業(yè)務 //其次執(zhí)行EventListeners.prepareSendProductListener()監(jiān)聽器,處理相關業(yè)務 //再次執(zhí)行EventListeners.sendProductListener()監(jiān)聽器,處理相關業(yè)務 //應用Spring事件,可以讓非主要業(yè)務和主要業(yè)務解耦,使用異步處理非主要業(yè)務,讓程序吞吐量即處理能力更強 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,啟動工程,模擬增加一個商品,相關截圖如下,可見商品增加事件已經觸發(fā),
http://localhost:8080/product/add?categoryCode=c01&productName=productName001&productCode=pc001&price=20.5&addNum=2&isHotSell=1
12,啟動工程,模擬建立一個訂單,相關截圖如下,可見訂單相關事件已經觸發(fā),
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的事件編程可以應用到很多的地方,合理應用可以使代碼主次業(yè)務分清,業(yè)務解耦,提高程序吞吐量,但需要開發(fā)人員掌握更多的知識,只要學習應該不是很難,習慣一種編程邏輯多一種開發(fā)思路,歡迎拍磚討論...
到此這篇關于詳解Java事件編程的使用的文章就介紹到這了,更多相關Java事件編程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java高效打印一個二維數組的實例(不用遞歸,不用兩個for循環(huán))
下面小編就為大家?guī)硪黄猨ava高效打印一個二維數組的實例(不用遞歸,不用兩個for循環(huán))。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-03-03Java中BufferedReader與BufferedWriter類的使用示例
BufferedReader與BufferedWriter分別繼承于Reader和Writer類,分別為字符的讀取和寫入添加緩沖功能,這里我們就來看一下Java中BufferedReader與BufferedWriter類的使用示例:2016-06-06