You've already forked FrameTour-BE
refactor(pricing): 优化优惠提供者初始化和依赖注入
- 使用 @Lazy 注解解决循环依赖问题 - 重构 DiscountDetectionServiceImpl 以延迟加载优惠提供者 - 移除构造函数中的直接依赖注入,改用 ObjectProvider - 添加线程安全的提供者初始化机制 - 移除不必要的缓存注释
This commit is contained in:
@@ -7,8 +7,8 @@ import com.ycwl.basic.pricing.service.ICouponService;
|
|||||||
import com.ycwl.basic.pricing.service.IDiscountProvider;
|
import com.ycwl.basic.pricing.service.IDiscountProvider;
|
||||||
import com.ycwl.basic.pricing.service.IPriceBundleService;
|
import com.ycwl.basic.pricing.service.IPriceBundleService;
|
||||||
import com.ycwl.basic.pricing.service.IProductConfigService;
|
import com.ycwl.basic.pricing.service.IProductConfigService;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
@@ -20,13 +20,20 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class CouponDiscountProvider implements IDiscountProvider {
|
public class CouponDiscountProvider implements IDiscountProvider {
|
||||||
|
|
||||||
private final ICouponService couponService;
|
private final ICouponService couponService;
|
||||||
private final IProductConfigService productConfigService;
|
private final IProductConfigService productConfigService;
|
||||||
private final IPriceBundleService bundleService;
|
private final IPriceBundleService bundleService;
|
||||||
|
|
||||||
|
public CouponDiscountProvider(@Lazy ICouponService couponService,
|
||||||
|
@Lazy IProductConfigService productConfigService,
|
||||||
|
@Lazy IPriceBundleService bundleService) {
|
||||||
|
this.couponService = couponService;
|
||||||
|
this.productConfigService = productConfigService;
|
||||||
|
this.bundleService = bundleService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getProviderType() {
|
public String getProviderType() {
|
||||||
return "COUPON";
|
return "COUPON";
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.ycwl.basic.pricing.dto.*;
|
|||||||
import com.ycwl.basic.pricing.service.IDiscountDetectionService;
|
import com.ycwl.basic.pricing.service.IDiscountDetectionService;
|
||||||
import com.ycwl.basic.pricing.service.IDiscountProvider;
|
import com.ycwl.basic.pricing.service.IDiscountProvider;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -20,21 +21,19 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class DiscountDetectionServiceImpl implements IDiscountDetectionService {
|
public class DiscountDetectionServiceImpl implements IDiscountDetectionService {
|
||||||
|
|
||||||
|
private final ObjectProvider<IDiscountProvider> discountProviderProvider;
|
||||||
private final List<IDiscountProvider> discountProviders = new ArrayList<>();
|
private final List<IDiscountProvider> discountProviders = new ArrayList<>();
|
||||||
|
private final Object providerInitLock = new Object();
|
||||||
|
private volatile boolean providersInitialized;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DiscountDetectionServiceImpl(List<IDiscountProvider> providers) {
|
public DiscountDetectionServiceImpl(ObjectProvider<IDiscountProvider> discountProviderProvider) {
|
||||||
this.discountProviders.addAll(providers);
|
this.discountProviderProvider = discountProviderProvider;
|
||||||
// 按优先级排序(优先级高的在前)
|
|
||||||
this.discountProviders.sort(Comparator.comparing(IDiscountProvider::getPriority).reversed());
|
|
||||||
|
|
||||||
log.info("注册了 {} 个优惠提供者: {}",
|
|
||||||
providers.size(),
|
|
||||||
providers.stream().map(IDiscountProvider::getProviderType).collect(Collectors.toList()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DiscountInfo> detectAllAvailableDiscounts(DiscountDetectionContext context) {
|
public List<DiscountInfo> detectAllAvailableDiscounts(DiscountDetectionContext context) {
|
||||||
|
initializeProvidersIfNecessary();
|
||||||
List<DiscountInfo> allDiscounts = new ArrayList<>();
|
List<DiscountInfo> allDiscounts = new ArrayList<>();
|
||||||
|
|
||||||
for (IDiscountProvider provider : discountProviders) {
|
for (IDiscountProvider provider : discountProviders) {
|
||||||
@@ -151,16 +150,22 @@ public class DiscountDetectionServiceImpl implements IDiscountDetectionService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerProvider(IDiscountProvider provider) {
|
public void registerProvider(IDiscountProvider provider) {
|
||||||
if (provider != null && !discountProviders.contains(provider)) {
|
if (provider == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (providerInitLock) {
|
||||||
|
initializeProvidersIfNecessary();
|
||||||
|
if (!discountProviders.contains(provider)) {
|
||||||
discountProviders.add(provider);
|
discountProviders.add(provider);
|
||||||
// 重新排序
|
|
||||||
discountProviders.sort(Comparator.comparing(IDiscountProvider::getPriority).reversed());
|
discountProviders.sort(Comparator.comparing(IDiscountProvider::getPriority).reversed());
|
||||||
log.info("注册新的优惠提供者: {}", provider.getProviderType());
|
log.info("注册新的优惠提供者: {}", provider.getProviderType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IDiscountProvider> getAllProviders() {
|
public List<IDiscountProvider> getAllProviders() {
|
||||||
|
initializeProvidersIfNecessary();
|
||||||
return new ArrayList<>(discountProviders);
|
return new ArrayList<>(discountProviders);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +173,7 @@ public class DiscountDetectionServiceImpl implements IDiscountDetectionService {
|
|||||||
* 查找指定类型的优惠提供者
|
* 查找指定类型的优惠提供者
|
||||||
*/
|
*/
|
||||||
private IDiscountProvider findProvider(String providerType) {
|
private IDiscountProvider findProvider(String providerType) {
|
||||||
|
initializeProvidersIfNecessary();
|
||||||
return discountProviders.stream()
|
return discountProviders.stream()
|
||||||
.filter(provider -> providerType.equals(provider.getProviderType()))
|
.filter(provider -> providerType.equals(provider.getProviderType()))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
@@ -203,4 +209,22 @@ public class DiscountDetectionServiceImpl implements IDiscountDetectionService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initializeProvidersIfNecessary() {
|
||||||
|
if (providersInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
synchronized (providerInitLock) {
|
||||||
|
if (providersInitialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
discountProviders.clear();
|
||||||
|
discountProviderProvider.stream().forEach(discountProviders::add);
|
||||||
|
discountProviders.sort(Comparator.comparing(IDiscountProvider::getPriority).reversed());
|
||||||
|
log.info("注册了 {} 个优惠提供者: {}",
|
||||||
|
discountProviders.size(),
|
||||||
|
discountProviders.stream().map(IDiscountProvider::getProviderType).collect(Collectors.toList()));
|
||||||
|
providersInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -97,13 +97,11 @@ public class PriceBundleServiceImpl implements IPriceBundleService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "active-bundles")
|
|
||||||
public List<PriceBundleConfig> getActiveBundles() {
|
public List<PriceBundleConfig> getActiveBundles() {
|
||||||
return bundleConfigMapper.selectActiveBundles();
|
return bundleConfigMapper.selectActiveBundles();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "all-bundles")
|
|
||||||
public List<PriceBundleConfig> getAllBundles() {
|
public List<PriceBundleConfig> getAllBundles() {
|
||||||
return bundleConfigMapper.selectActiveBundles();
|
return bundleConfigMapper.selectActiveBundles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,11 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
|||||||
private final PriceTierConfigMapper tierConfigMapper;
|
private final PriceTierConfigMapper tierConfigMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "product-config", key = "#productType")
|
|
||||||
public List<PriceProductConfig> getProductConfig(String productType) {
|
public List<PriceProductConfig> getProductConfig(String productType) {
|
||||||
return productConfigMapper.selectByProductType(productType);
|
return productConfigMapper.selectByProductType(productType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "product-config", key = "#productType + '_' + #productId")
|
|
||||||
public PriceProductConfig getProductConfig(String productType, String productId) {
|
public PriceProductConfig getProductConfig(String productType, String productId) {
|
||||||
PriceProductConfig config = productConfigMapper.selectByProductTypeAndId(productType, productId);
|
PriceProductConfig config = productConfigMapper.selectByProductTypeAndId(productType, productId);
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
@@ -46,7 +44,6 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "tier-config", key = "#productType + '_' + #productId + '_' + #quantity")
|
|
||||||
public PriceTierConfig getTierConfig(String productType, String productId, Integer quantity) {
|
public PriceTierConfig getTierConfig(String productType, String productId, Integer quantity) {
|
||||||
if (quantity == null || quantity <= 0) {
|
if (quantity == null || quantity <= 0) {
|
||||||
return null;
|
return null;
|
||||||
@@ -73,7 +70,6 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "product-config", key = "#productType + '_' + #productId + '_' + #scenicId")
|
|
||||||
public PriceProductConfig getProductConfig(String productType, String productId, Long scenicId) {
|
public PriceProductConfig getProductConfig(String productType, String productId, Long scenicId) {
|
||||||
if (scenicId == null) {
|
if (scenicId == null) {
|
||||||
// 如果没有景区ID,使用原有逻辑
|
// 如果没有景区ID,使用原有逻辑
|
||||||
@@ -124,7 +120,6 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "tier-config", key = "#productType + '_' + #productId + '_' + #quantity + '_' + #scenicId")
|
|
||||||
public PriceTierConfig getTierConfig(String productType, String productId, Integer quantity, Long scenicId) {
|
public PriceTierConfig getTierConfig(String productType, String productId, Integer quantity, Long scenicId) {
|
||||||
if (quantity == null || quantity <= 0) {
|
if (quantity == null || quantity <= 0) {
|
||||||
return null;
|
return null;
|
||||||
@@ -174,31 +169,26 @@ public class ProductConfigServiceImpl implements IProductConfigService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "active-product-configs")
|
|
||||||
public List<PriceProductConfig> getActiveProductConfigs() {
|
public List<PriceProductConfig> getActiveProductConfigs() {
|
||||||
return productConfigMapper.selectActiveConfigs();
|
return productConfigMapper.selectActiveConfigs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "all-product-configs")
|
|
||||||
public List<PriceProductConfig> getAllProductConfigs() {
|
public List<PriceProductConfig> getAllProductConfigs() {
|
||||||
return productConfigMapper.selectActiveConfigs();
|
return productConfigMapper.selectActiveConfigs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "tier-configs", key = "#productType")
|
|
||||||
public List<PriceTierConfig> getTierConfigs(String productType) {
|
public List<PriceTierConfig> getTierConfigs(String productType) {
|
||||||
return tierConfigMapper.selectByProductType(productType);
|
return tierConfigMapper.selectByProductType(productType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "tier-configs", key = "#productType + '_' + #productId")
|
|
||||||
public List<PriceTierConfig> getTierConfigs(String productType, String productId) {
|
public List<PriceTierConfig> getTierConfigs(String productType, String productId) {
|
||||||
return tierConfigMapper.selectByProductTypeAndId(productType, productId);
|
return tierConfigMapper.selectByProductTypeAndId(productType, productId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
// @Cacheable(value = "all-tier-configs")
|
|
||||||
public List<PriceTierConfig> getAllTierConfigs() {
|
public List<PriceTierConfig> getAllTierConfigs() {
|
||||||
return tierConfigMapper.selectAllActiveConfigs();
|
return tierConfigMapper.selectAllActiveConfigs();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user