最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java事件編程的使用

 更新時間:2021年06月18日 09:59:59   作者:shenzhenNBA  
Java事件在很多地方都可以使用,合理的使用事件編程,相比常規(guī)邏輯的編程,這可達到主次分明,讓程序吞吐量即處理能力更強,改動更少,下面我們舉一個例子說明如何使用Java使用,需要的朋友可以參考下

Java事件編程

當前在線網(wǎng)店很多,很涉及商品管理和銷售的問題,比如:

一,在商品庫存管理的商品增加時,我們主要業(yè)務(wù)時編輯保持商品信息,

同時因商品增加而附帶有一些“非主要業(yè)務(wù)”,如:

1,應(yīng)商品的庫存數(shù)量等更新,
2,熱銷產(chǎn)品的推廣處理等

二,在商品產(chǎn)生訂單時,我們的主要業(yè)務(wù)(對買家而言)是建立訂單業(yè)務(wù),

同時因產(chǎn)生訂單而附帶有一些不是買家關(guān)心的“非主要業(yè)務(wù)”,如:

1,庫存和已售數(shù)量的更新
2,發(fā)貨的準備處理事宜
3,物流的處理事宜

非主要業(yè)務(wù)我們可以讓程序使用多線程異步執(zhí)行,這樣主要業(yè)務(wù)和非主要業(yè)務(wù)就完全解耦,
主要業(yè)務(wù)可以快速完成響應(yīng),非主要業(yè)務(wù)多線程異步執(zhí)行,提高程序的吞吐量即高處理能力;
同時使用自定義的線程池,有比較好的把控;

下面我們就根據(jù)上面的場景需求編寫一個例子,看看在Springboot中如何Java的事件編程,
對比一下常規(guī)邏輯的編程,和采用Java事件編程的差異。

//常規(guī)邏輯的編程
@GetMapping(value="/add")  
@ResponseBody
public String addProduct(Product product) {
	
	
	//增加產(chǎn)品
	
	//應(yīng)商品的庫存數(shù)量等更新
	
	//是否為熱銷產(chǎn)品的推廣處理
	
	//其它處理
	
	return "產(chǎn)品增加完成";
}

主要業(yè)務(wù)是增加產(chǎn)品信息,但是可能會因產(chǎn)品庫存或熱銷產(chǎn)品等其它問題處理而收到影響,
耦合性比較強,如果以后還有其它需求又需要改動程序,問題暴露出來了;

同樣,下單也是一樣問題,主要業(yè)務(wù)是買家下單時建立訂單,

//常規(guī)邏輯的編程
@GetMapping(value="/createOrder")  
@ResponseBody
public String createProductOrder(ProductOrder productOrder) {
	
	
	//收集產(chǎn)品訂單信息,保持建立訂單
	
	//庫存和已售數(shù)量的更新
	
	//訂單備貨處理
	
	//物流處理
	
	return "產(chǎn)品訂單建立完成";
}

對買家來說,主要業(yè)務(wù)是產(chǎn)品下單,后續(xù)的庫存和已售數(shù)量的更新,備貨處理,物流處理等不是買家關(guān)心的,但是可能會因這些問題處理而受到影響,可能下單失敗,耦合性比較強,如果以后還有其它需求又需要改動程序,同樣問題暴露出來了;

那怎么建立主次分明的處理邏輯呢,這里用Java事件編程就很好處理這些問題,主次分明,完全解耦,程序改動比較小,程序吞吐量也強,
相關(guān)注釋在程序非常清楚,所以主要看代碼吧;

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

1,項目結(jié)構(gòu)如下圖: 

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;
 
/**
 * 配置異步任務(wù)線程池,然后注入springIOC容器,提供異步任務(wù)使用;
 * @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è)務(wù)相關(guān)需要的實體或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;		//增加數(shù)量
	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;
 
/**
 * 商品的數(shù)量和積分相關(guān)實體類
 * @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;		//已收數(shù)量
	private Long scoreNum;		//單個購買贈送積分數(shù)
	
	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;		//購買贈送積分數(shù)
	private Long buyNum;		//訂單購買數(shù)量
	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è)務(wù)的相關(guān)Java事件源,主要是編寫繼承 
org.springframework.context.ApplicationEvent 的類對象,
以及定義各事件相關(guān)的對象
,比如,商品對象,或訂單對象,事件源的目的是存儲事件相關(guān)的目標信息,參考如下代碼:

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)聽器和相關(guān)業(yè)務(wù)處理邏輯,并將其納入SpringIOC容器管理,
監(jiān)聽類方法加注解 @EventListener 使之變?yōu)橐粋€監(jiān)聽器,加注解@Async("asyncTaskExecutor") 指定監(jiān)聽器異步執(zhí)行,同時指定異步執(zhí)行使用的線程池,加注解  @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
指定監(jiān)聽器事務(wù)的階段, 一般為業(yè)務(wù)數(shù)據(jù)入庫之后,再異步執(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è)務(wù)處理邏輯,
 * 然后注入springIOC容器,并監(jiān)聽相應(yīng)的事件,只要觸發(fā)相應(yīng)事件則用對應(yīng)監(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)聽事務(wù)的階段,多數(shù)情況下的業(yè)務(wù)操作會涉及數(shù)據(jù)庫事務(wù),確保主業(yè)務(wù)的數(shù)據(jù)入庫后,再進行本方法的異步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定義本方法為一個監(jiān)聽器,處理因增加產(chǎn)品而引發(fā)的事件中有關(guān)產(chǎn)品庫存等數(shù)量相關(guān)信息
	@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("產(chǎn)品增加事件監(jiān)聽器 1, 事件關(guān)聯(lián)信息:{}", pes.getProduct());
		logger.info("");
		// TODO 有關(guān)產(chǎn)品數(shù)量的庫存等更新操作
	}
	
	
	//指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池
	@Async("asyncTaskExecutor")
	//指定監(jiān)聽事務(wù)的階段,多數(shù)情況下的業(yè)務(wù)操作會涉及數(shù)據(jù)庫事務(wù),確保主業(yè)務(wù)的數(shù)據(jù)入庫后,再進行本方法的異步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定義本方法為一個監(jiān)聽器,處理因增加產(chǎn)品而引發(fā)的事件中有關(guān)熱銷產(chǎn)品的相關(guān)促銷事宜
	@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("產(chǎn)品增加事件監(jiān)聽器 2, 事件關(guān)聯(lián)信息:{}", pes.getProduct());
		logger.info("");
		if (null == pes.getProduct()) {
			return;
		}
		if (1 != pes.getProduct().getIsHotSell().intValue()) {
			logger.info("產(chǎn)品增加事件監(jiān)聽器 2, 非熱銷產(chǎn)品");
			return;
		}
		// TODO 有關(guān)熱銷產(chǎn)品的相關(guān)促銷事宜的處理
	}
	
	
	//指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池
	@Async("asyncTaskExecutor")
	//指定監(jiān)聽事務(wù)的階段,多數(shù)情況下的業(yè)務(wù)操作會涉及數(shù)據(jù)庫事務(wù),確保主業(yè)務(wù)的數(shù)據(jù)入庫后,再進行本方法的異步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定義本方法為一個監(jiān)聽器,處理因產(chǎn)品產(chǎn)生訂單而引發(fā)的事件中有關(guān)產(chǎn)品庫存和已售數(shù)量相關(guān)信息
	@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("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 1, 事件關(guān)聯(lián)信息:{}", poes.getProductOrder());
		logger.info("");
		// TODO 有關(guān)產(chǎn)品數(shù)量的庫存和已售數(shù)量更新操作
	}
	
	
	//指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池
	@Async("asyncTaskExecutor")
	//指定監(jiān)聽事務(wù)的階段,多數(shù)情況下的業(yè)務(wù)操作會涉及數(shù)據(jù)庫事務(wù),確保主業(yè)務(wù)的數(shù)據(jù)入庫后,再進行本方法的異步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定義本方法為一個監(jiān)聽器,處理因產(chǎn)品產(chǎn)生訂單而引發(fā)的事件中有關(guān)產(chǎn)品發(fā)貨的相關(guān)準備和處理事宜
	@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("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 2, 事件關(guān)聯(lián)信息:{}", proOrder);
		logger.info("");
		if (null != proOrder.getIsSendOut() && 
				1 == proOrder.getIsSendOut()) {
			logger.info("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 2, 訂單已經(jīng)發(fā)貨,不用再處理");
			return;
		}
		if (null != proOrder.getIsPrepared() && 
				1 == proOrder.getIsPrepared()) {
			logger.info("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 2, 訂單發(fā)貨準備已經(jīng)完成,不用再處理");
			return;
		}
		// TODO 有關(guān)產(chǎn)品訂單發(fā)貨的事宜
	}
	
		
	//指定異步執(zhí)行監(jiān)聽器,同時使用的自定義的異步線程池
	@Async("asyncTaskExecutor")
	//指定監(jiān)聽事務(wù)的階段,多數(shù)情況下的業(yè)務(wù)操作會涉及數(shù)據(jù)庫事務(wù),確保主業(yè)務(wù)的數(shù)據(jù)入庫后,再進行本方法的異步操作
	@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
	//注解定義本方法為一個監(jiān)聽器,處理因產(chǎn)品產(chǎn)生訂單而引發(fā)的事件中有關(guān)產(chǎn)品發(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("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 3, 事件關(guān)聯(lián)信息:{}", poes.getProductOrder());
		logger.info("");
		if (null != proOrder.getIsSendOut() && 
				1 == proOrder.getIsSendOut()) {
			logger.info("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 3, 訂單已經(jīng)發(fā)貨,不用再處理");
			return;
		}
		if (null != proOrder.getIsPrepared() && 
				0 == proOrder.getIsPrepared().intValue()) {
			logger.info("產(chǎn)品產(chǎn)生訂單事件監(jiān)聽器 3, 訂單發(fā)貨準備還未完成,先等備好貨,再處理物流事宜");
		}
		// TODO 有關(guān)產(chǎn)品訂單的物流事宜
	}	
	
}

6,定義業(yè)務(wù)接口,參考如下代碼:

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 {
	
	/**
	 * 增加產(chǎn)品
	 * @author shenzhenNBA
	 * @param product
	 * @return
	 */
	Integer addProduct(Product product);
	
	/**
	 * 根據(jù)產(chǎn)品代碼查詢產(chǎn)品記錄
	 * @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 {
 
	/**
	 * 建立產(chǎn)品訂單
	 * @author shenzhenNBA
	 * @param product
	 * @return
	 */
	Integer createProductOrder(ProductOrder productOrder);
	
	/**
	 * 根據(jù)產(chǎn)品訂單代碼查詢產(chǎn)品訂單記錄
	 * @author shenzhenNBA
	 * @param product
	 * @return
	 */
	Product getProductOrder(String productOrderCode);
	
}

7,實現(xiàn)所定義的業(yè)務(wù)接口,參考如下代碼:

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接口實現(xiàn)類
 * @author shenzhenNBA
 * @since 2021/06/14
 */
 
@Service
public class ProductServiceImpl implements ProductService {
 
	private static final long serialVersionUID = 20210606010090L;
	
	/**
	 * 增加產(chǎn)品
	 */
	@Override
	public Integer addProduct(Product product) {
		// TODO more biz handle here
		return null;
	}
 
	/**
	 * 根據(jù)產(chǎn)品代碼查詢產(chǎn)品記錄
	 */
	@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接口實現(xiàn)類
 * @author shenzhenNBA
 * @since 2021/06/14
 */
@Service
public class ProductOrderServiceImpl implements ProductOrderService {
 
	private static final long serialVersionUID = 20210606010100L;
	
	/**
	 * 建立產(chǎn)品訂單
	 */
	@Override
	public Integer createProductOrder(ProductOrder productOrder) {
		// TODO more biz handle here
		return null;
	}
 
	/**
	 * 根據(jù)產(chǎn)品訂單代碼查詢產(chǎn)品訂單記錄
	 */
	@Override
	public Product getProductOrder(String productOrderCode) {
		// TODO more biz handle here
		return null;
	}
}

8,在對外API(即controller層)接口中處理業(yè)務(wù),同時使用 org.springframework.context.ApplicationEventPublisher 
實例發(fā)布相應(yīng)的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事件編程方式實現(xiàn),
 * 產(chǎn)品對外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è)務(wù),增加產(chǎn)品
		productService.addProduct(product);
		
		//?categoryCode=c01&productName=productName001&productCode=pc001&price=20.5&addNum=2&isHotSell=1
		//因增加產(chǎn)品而發(fā)布與其相關(guān)的事件,處理與之相關(guān)的非主要業(yè)務(wù),
		//首先執(zhí)行EventListeners.updateProductReferNumListener()監(jiān)聽器,處理相關(guān)業(yè)務(wù)
		//其次執(zhí)行EventListeners.handleHotSellProductListener()監(jiān)聽器,處理相關(guān)業(yè)務(wù)
		//應(yīng)用Spring事件,可以讓非主要業(yè)務(wù)和主要業(yè)務(wù)解耦,使用異步處理非主要業(yè)務(wù),讓程序吞吐量即處理能力更強
		appEventPublisher.publishEvent(new ProductEventSource(product));
		
		return "產(chǎn)品增加完成";
	}
}
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事件編程方式實現(xiàn),
 * 產(chǎn)品訂單對外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è)務(wù),增加產(chǎn)品
		productOrderService.createProductOrder(productOrder);
		
		//?productCode=pc001&productName=productName001&price=20.5&buyNum=3&
		//scoreNum=0&warehouseCode=house01&recieveAddress=add001
		//因增加產(chǎn)品而發(fā)布與其相關(guān)的事件,處理與之相關(guān)的非主要業(yè)務(wù),
		//首先執(zhí)行EventListeners.updateProductReferNumListener()監(jiān)聽器,處理相關(guān)業(yè)務(wù)
		//其次執(zhí)行EventListeners.prepareSendProductListener()監(jiān)聽器,處理相關(guān)業(yè)務(wù)
		//再次執(zhí)行EventListeners.sendProductListener()監(jiān)聽器,處理相關(guān)業(yè)務(wù)
		//應(yīng)用Spring事件,可以讓非主要業(yè)務(wù)和主要業(yè)務(wù)解耦,使用異步處理非主要業(yè)務(wù),讓程序吞吐量即處理能力更強
		appEventPublisher.publishEvent(new ProductOrderEventSource(productOrder));
		
		return "產(chǎn)品訂單建立完成";
	}
}

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,啟動工程,模擬增加一個商品,相關(guān)截圖如下,可見商品增加事件已經(jīng)觸發(fā),

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

12,啟動工程,模擬建立一個訂單,相關(guān)截圖如下,可見訂單相關(guān)事件已經(jīng)觸發(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īng)用到很多的地方,合理應(yīng)用可以使代碼主次業(yè)務(wù)分清,業(yè)務(wù)解耦,提高程序吞吐量,但需要開發(fā)人員掌握更多的知識,只要學(xué)習(xí)應(yīng)該不是很難,習(xí)慣一種編程邏輯多一種開發(fā)思路,歡迎拍磚討論...

到此這篇關(guān)于詳解Java事件編程的使用的文章就介紹到這了,更多相關(guān)Java事件編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringMVC?RESTFul實戰(zhàn)案例訪問首頁

    SpringMVC?RESTFul實戰(zhàn)案例訪問首頁

    這篇文章主要為大家介紹了SpringMVC?RESTFul實戰(zhàn)案例訪問首頁,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • java繼承中的構(gòu)造方法實例解析

    java繼承中的構(gòu)造方法實例解析

    這篇文章主要介紹了java繼承中的構(gòu)造方法實例解析,針對繼承中的構(gòu)造方法的特點進行了實例分析,需要的朋友可以參考下
    2014-10-10
  • 關(guān)于Java創(chuàng)建線程的2種方式以及對比

    關(guān)于Java創(chuàng)建線程的2種方式以及對比

    這篇文章主要給大家介紹了關(guān)于Java創(chuàng)建線程的2種方式以及對比的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-01-01
  • Springboot整合hibernate validator 全局異常處理步驟詳解

    Springboot整合hibernate validator 全局異常處理步驟詳解

    本文分步驟給大家介紹Springboot整合hibernate validator 全局異常處理,補呢文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • 淺談什么是SpringBoot異常處理自動配置的原理

    淺談什么是SpringBoot異常處理自動配置的原理

    今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著SpringBoot異常處理自動配置展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 基于java中集合的概念(詳解)

    基于java中集合的概念(詳解)

    下面小編就為大家?guī)硪黄趈ava中集合的概念(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • SpringCloudStream原理和深入使用小結(jié)

    SpringCloudStream原理和深入使用小結(jié)

    Spring?Cloud?Stream是一個用于構(gòu)建與共享消息傳遞系統(tǒng)連接的高度可擴展的事件驅(qū)動型微服務(wù)的框架,本文給大家介紹SpringCloudStream原理和深入使用,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • Spring Boot 2.x中Actuator的一些知識點

    Spring Boot 2.x中Actuator的一些知識點

    這篇文章主要給大家介紹了關(guān)于Spring Boot 2.x中Actuator的一些知識點,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Spring Boot 2.x具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Java基礎(chǔ)之Filter的實例詳解

    Java基礎(chǔ)之Filter的實例詳解

    這篇文章主要介紹了Java基礎(chǔ)之Filter的實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-07-07
  • Spring AOP底層源碼詳解

    Spring AOP底層源碼詳解

    這篇文章主要介紹了Spring AOP底層源碼詳解,幫助大家更好的理解和學(xué)習(xí)使用Spring AOP,感興趣的朋友可以了解下
    2021-03-03

最新評論

祁门县| 贞丰县| 江川县| 松江区| 大新县| 慈利县| 莱州市| 武宣县| 罗田县| 宁夏| 聂荣县| 治多县| 民权县| 淳化县| 通化县| 建德市| 乌拉特后旗| 迁西县| 汕尾市| 芜湖市| 石门县| 宁河县| 海南省| 观塘区| 濉溪县| 大邑县| 巴林左旗| 迁西县| 潮安县| 开化县| 婺源县| 莱阳市| 南投县| 湘西| 德保县| 仙游县| 北宁市| 盘锦市| 突泉县| 涿鹿县| 昌宁县|