applicationContext.getBeansOfType获取到的子类Bean不全

使用Spring的applicationContext.getBeansOfType获取到的子类Bean不全,代码如下:

工厂类:

package cn.com.kemai.open.service.submsg;

import cn.com.kemai.open.remote.enums.SubMsgBusinessTypeEnum;
import cn.com.kemai.open.remote.util.ValidUtils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 微信订阅消息服务工厂
 *
 * @author leiguoqing
 * @date 2022 -2-18 14:00
 */
@Slf4j
@Service
public class WxMaSubMsgServiceFactory implements ApplicationContextAware {

    /**
     * 策略实现类保存到 Map 中 Key 的前缀
     */
    private static final String KEY_PREFIX = "wxMaSubMsgServiceTemplate";

    /**
     * 用于保存所有策略实现类
     */
    private final Map<String, WxMaSubMsgServiceTemplate> wxMaSubMsgServiceTemplateMap = Maps.newConcurrentMap();

    /**
     * 获取微信订阅消息服务
     *
     * @param busType the bus type
     * @return the wx ma sub msg service
     */
    public WxMaSubMsgServiceTemplate getService(SubMsgBusinessTypeEnum busType) {
        final WxMaSubMsgServiceTemplate wxMaSubMsgServiceTemplate = wxMaSubMsgServiceTemplateMap.get(KEY_PREFIX + busType.getCode());
        ValidUtils.isNull(wxMaSubMsgServiceTemplate, "获取微信订阅消息服务策略异常,请检查订阅消息业务类型");
        return wxMaSubMsgServiceTemplate;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // key 默认是以实现类的名称,首字母小写名称
        final Map<String, WxMaSubMsgServiceTemplate> templateMap = applicationContext.getBeansOfType(WxMaSubMsgServiceTemplate.class);
        if (MapUtils.isEmpty(templateMap)) {
            return;
        }

        // 转化为我们自定义的名称
        templateMap.values().forEach(templateObj -> {
            final Integer code = templateObj.getBusinessType().getCode();
            log.info("WxMaSubMsgService BusinessType code = {}", code);
            wxMaSubMsgServiceTemplateMap.put(KEY_PREFIX + code, templateObj);
        });

        wxMaSubMsgServiceTemplateMap.forEach((k, v) -> log.info("init WxMaSubMsgService bean success, name = {},bean = {}", k, v.toString()));
    }
}

模板父类:

package cn.com.kemai.open.service.submsg;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.com.kemai.open.properties.WxMaSubMsgProperties;
import cn.com.kemai.open.remote.enums.SubMsgBusinessTypeEnum;
import cn.com.kemai.open.service.IMaAccountService;
import cn.com.kemai.open.service.IMaSubMsgSendRecordService;
import cn.com.kemai.open.service.submsg.data.SubMsgData;
import cn.com.kemai.open.util.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxMaErrorMsgEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Objects;

/**
 * 微信订阅消息服务模板
 *
 * @author leiguoqing
 * @date 2022 -2-18 9:29
 */
@Slf4j
public abstract class WxMaSubMsgServiceTemplate implements SubMsgCallBack {

    /**
     * 发送订阅消息
     *
     * @param accountId   微信小程序账户id
     * @param businessIds 业务ids
     * @param subMsgData  微信订阅消息参数
     */
    public final void sendMsg(Long accountId, List<Long> businessIds, SubMsgData subMsgData) {
        Assert.notNull(accountId, "accountId must not null");
        Assert.notEmpty(businessIds, "businessIds must not null");
        Assert.notNull(subMsgData, "subMsgData must not null");

        final Boolean enable = getSpringBean(WxMaSubMsgProperties.class).getEnable();
        if (!enable) {
            return;
        }

        // 构建 MsgData
        final List<WxMaSubscribeMessage.MsgData> msgDatas = this.buildMsgData(subMsgData.getMsgDataValues());
        if (CollectionUtils.isEmpty(msgDatas)) {
            return;
        }

        // 构建 WxMaSubscribeMessage
        final WxMaSubscribeMessage wxMaSubscribeMessage = this.buildWxMaSubscribeMessage(getSpringBean(IMaAccountService.class).getOpenIdById(accountId), msgDatas);
        if (Objects.isNull(wxMaSubscribeMessage)) {
            return;
        }

        // 默认发送成功
        WxError wxError = WxError.builder().errorCode(0).errorMsg("成功").build();

        // 发送订阅消息
        try {
            getSpringBean(WxMaService.class).getSubscribeService().sendSubscribeMsg(wxMaSubscribeMessage);
        } catch (WxErrorException e) {
            wxError = e.getError();
            if (wxError.getErrorCode() != WxMaErrorMsgEnum.CODE_43101.getCode()) {
                log.error("推送核销订阅消息异常:", e);
            }
        }

        // 保存订阅消息发送记录
        getSpringBean(IMaSubMsgSendRecordService.class).saveRecord(accountId, businessIds, wxError, this.getBusinessType());

        // 回调
        this.callBack(accountId, businessIds);
    }



    /**
     * 获取业务类型
     *
     * @return the business type
     */
    protected abstract SubMsgBusinessTypeEnum getBusinessType();


    /**
     * 构建 MsgData 参数
     * <br/>
     * 可以使用 {@link WxMaSubMsgServiceTemplate#newMsgData(String, String)} 方法构建
     *
     * @param msgDataValues the msg data values
     * @return the list
     */
    protected abstract List<WxMaSubscribeMessage.MsgData> buildMsgData(List<String> msgDataValues);

    /**
     * 构建 WxMaSubscribeMessage 参数
     *
     * @param toUserOpenId the to user open id
     * @param msgDatas     the msg datas
     * @return the wx ma subscribe message
     */
    protected abstract WxMaSubscribeMessage buildWxMaSubscribeMessage(String toUserOpenId, List<WxMaSubscribeMessage.MsgData> msgDatas);


    /**
     * 创建一个 MsgData
     *
     * @param name  the name
     * @param value the value
     * @return the wx ma subscribe message . msg data
     */
    protected final WxMaSubscribeMessage.MsgData newMsgData(String name, String value) {
        WxMaSubscribeMessage.MsgData msgData = new WxMaSubscribeMessage.MsgData();
        msgData.setName(name);
        msgData.setValue(value);
        return msgData;
    }


    private <T> T getSpringBean(Class<T> cls) {
        return SpringContextUtils.getBean(cls);
    }

}

3个子类:

package cn.com.kemai.open.service.submsg;

import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.com.kemai.open.constant.SystemConstants;
import cn.com.kemai.open.properties.WxMaSubMsgProperties;
import cn.com.kemai.open.remote.enums.SubMsgBusinessTypeEnum;
import cn.com.kemai.open.service.IMaAccountCouponService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 微信小程序优惠券过期订阅消息服务
 *
 * @author leiguoqing
 * @date 2022 -1-20 11:39
 */
@RequiredArgsConstructor
@Service
public class ExpiredWxMaSubMsgService extends WxMaSubMsgServiceTemplate {

    /**
     * 微信小程序订阅消息参数配置
     */
    private final WxMaSubMsgProperties wxMaSubMsgProperties;

    /**
     * 小程序账户-门店优惠券关联表
     */
    private final IMaAccountCouponService maAccountCouponService;


    /**
     * 获取业务类型
     *
     * @return the business type
     */
    @Override
    protected SubMsgBusinessTypeEnum getBusinessType() {
        return SubMsgBusinessTypeEnum.COUPON_EXPIRED;
    }


    /**
     * 构建 MsgData 参数
     *
     * @param msgDataValues the msg data values
     * @return the list
     */
    @Override
    protected List<WxMaSubscribeMessage.MsgData> buildMsgData(List<String> msgDataValues) {
        return IntStream.range(0, msgDataValues.size())
                .mapToObj(idx -> super.newMsgData(wxMaSubMsgProperties.getExpiredTempMsgDataNames()[idx], msgDataValues.get(idx)))
                .collect(Collectors.toList());
    }

    /**
     * 构建 WxMaSubscribeMessage 参数
     *
     * @param toUserOpenId the to user open id
     * @param msgDatas     the msg datas
     * @return the wx ma subscribe message
     */
    @Override
    protected WxMaSubscribeMessage buildWxMaSubscribeMessage(String toUserOpenId, List<WxMaSubscribeMessage.MsgData> msgDatas) {
        return WxMaSubscribeMessage.builder()
                .templateId(wxMaSubMsgProperties.getExpiredTempId())
                .toUser(toUserOpenId)
                .page(SystemConstants.WX_MA_SUB_MSG_JUMP_PAGE)
                // 消息参数
                .data(msgDatas)
                .miniprogramState(wxMaSubMsgProperties.getState())
                .build();
    }

    /**
     * 发送消息后回调
     *
     * @param accountId   微信小程序账户id
     * @param businessIds 业务ids
     */
    @Override
    public void callBack(Long accountId, List<Long> businessIds) {
        // 修改该优惠券 “是否发送过期订阅通知” 标志
        maAccountCouponService.updateBatchSendExpiredSubMsgToTrue(businessIds);
    }
}
package cn.com.kemai.open.service.submsg;

import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.com.kemai.open.constant.SystemConstants;
import cn.com.kemai.open.properties.WxMaSubMsgProperties;
import cn.com.kemai.open.remote.enums.SubMsgBusinessTypeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 微信小程序到账订阅消息服务
 *
 * @author leiguoqing
 * @date 2022 -1-20 11:39
 */
@RequiredArgsConstructor
@Service
public class ReceiveWxMaSubMsgService extends WxMaSubMsgServiceTemplate {

    /**
     * 微信小程序订阅消息参数配置
     */
    private final WxMaSubMsgProperties wxMaSubMsgProperties;


    /**
     * 获取业务类型
     *
     * @return the business type
     */
    @Override
    protected SubMsgBusinessTypeEnum getBusinessType() {
        return SubMsgBusinessTypeEnum.COUPON_RECEIVE;
    }


    /**
     * 构建 MsgData 参数
     *
     * @param msgDataValues the msg data values
     * @return the list
     */
    @Override
    protected List<WxMaSubscribeMessage.MsgData> buildMsgData(List<String> msgDataValues) {
        return IntStream.range(0, msgDataValues.size())
                .mapToObj(idx -> super.newMsgData(wxMaSubMsgProperties.getReceiveTempMsgDataNames()[idx], msgDataValues.get(idx)))
                .collect(Collectors.toList());
    }

    /**
     * 构建 WxMaSubscribeMessage 参数
     *
     * @param toUserOpenId the to user open id
     * @param msgDatas     the msg datas
     * @return the wx ma subscribe message
     */
    @Override
    protected WxMaSubscribeMessage buildWxMaSubscribeMessage(String toUserOpenId, List<WxMaSubscribeMessage.MsgData> msgDatas) {
        return WxMaSubscribeMessage.builder()
                .templateId(wxMaSubMsgProperties.getReceiveTempId())
                .toUser(toUserOpenId)
                .page(SystemConstants.WX_MA_SUB_MSG_JUMP_PAGE)
                // 消息参数
                .data(msgDatas)
                .miniprogramState(wxMaSubMsgProperties.getState())
                .build();
    }
}
package cn.com.kemai.open.service.submsg;

import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage;
import cn.com.kemai.open.constant.SystemConstants;
import cn.com.kemai.open.properties.WxMaSubMsgProperties;
import cn.com.kemai.open.remote.enums.SubMsgBusinessTypeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 微信小程序核销订阅消息服务
 *
 * @author leiguoqing
 * @date 2022 -1-20 11:39
 */
@RequiredArgsConstructor
@Service
public class WriteOffWxMaSubMsgService extends WxMaSubMsgServiceTemplate {

    /**
     * 微信小程序订阅消息参数配置
     */
    private final WxMaSubMsgProperties wxMaSubMsgProperties;


    /**
     * 获取业务类型
     *
     * @return the business type
     */
    @Override
    protected SubMsgBusinessTypeEnum getBusinessType() {
        return SubMsgBusinessTypeEnum.COUPON_WRITE_OFF;
    }


    /**
     * 构建 MsgData 参数
     *
     * @param msgDataValues the msg data values
     * @return the list
     */
    @Override
    protected List<WxMaSubscribeMessage.MsgData> buildMsgData(List<String> msgDataValues) {
        return IntStream.range(0, msgDataValues.size())
                .mapToObj(idx -> super.newMsgData(wxMaSubMsgProperties.getWriteOffTempMsgDataNames()[idx], msgDataValues.get(idx)))
                .collect(Collectors.toList());
    }

    /**
     * 构建 WxMaSubscribeMessage 参数
     *
     * @param toUserOpenId the to user open id
     * @param msgDatas     the msg datas
     * @return the wx ma subscribe message
     */
    @Override
    protected WxMaSubscribeMessage buildWxMaSubscribeMessage(String toUserOpenId, List<WxMaSubscribeMessage.MsgData> msgDatas) {
        return WxMaSubscribeMessage.builder()
                .templateId(wxMaSubMsgProperties.getWriteOffTempId())
                .toUser(toUserOpenId)
                .page(SystemConstants.WX_MA_SUB_MSG_JUMP_PAGE)
                // 消息参数
                .data(msgDatas)
                .miniprogramState(wxMaSubMsgProperties.getState())
                .build();
    }
}

控制台只输入两个子类,另外一个没有获取到:

2022-03-01 10:55:20,278 INFO  main c.c.k.o.s.s.WxMaSubMsgServiceFactory 58 lambda$setApplicationContext$0 ---- WxMaSubMsgService BusinessType code = 1
2022-03-01 10:55:20,279 INFO  main c.c.k.o.s.s.WxMaSubMsgServiceFactory 58 lambda$setApplicationContext$0 ---- WxMaSubMsgService BusinessType code = 3
2022-03-01 10:55:20,280 INFO  main c.c.k.o.s.s.WxMaSubMsgServiceFactory 62 lambda$setApplicationContext$1 ---- init WxMaSubMsgService bean success, name = wxMaSubMsgServiceTemplate1,bean = cn.com.kemai.open.service.submsg.ReceiveWxMaSubMsgService@6d997b16
2022-03-01 10:55:20,281 INFO  main c.c.k.o.s.s.WxMaSubMsgServiceFactory 62 lambda$setApplicationContext$1 ---- init WxMaSubMsgService bean success, name = wxMaSubMsgServiceTemplate3,bean = cn.com.kemai.open.service.submsg.WriteOffWxMaSubMsgService@1f762537

 

 

 

请登录后发表评论