spring-starter基于微信公众号推送消息的简单实现

原理

首先说说原理,我们知道使用一个公用的starter的时候,只需要将相应的依赖添加的Maven的配置文件当中即可,免去了自己需要引用很多依赖类,并且SpringBoot会自动进行类的自动配置。那么 SpringBoot 是如何知道要实例化哪些类,并进行自动配置的呢? 下面简单说一下。

首先,SpringBoot 在启动时会去依赖的starter包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的Jar包去扫描项目所依赖的Jar包,这类似于 Java 的 SPI 机制。

第二步,根据 spring.factories配置加载AutoConfigure类。

最后,根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context 上下文当中。

我们也可以使用@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自动配置哪些类。

废话不多说,上代码:

1、先实现starter部分

新建 一个maven项目,引入依赖如下:

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!--微信模版消息推送三方sdk-->
<dependency>
   <groupId>com.github.binarywang</groupId>
   <artifactId>weixin-java-mp</artifactId>
   <version>3.3.0</version>
</dependency>

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.8</version>
</dependency>
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-test</artifactId>
</dependency>

2、定义属性配置类,用于引用时配置在application.properties文件中

package com.soyunn.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @Author: AaronNg
 * @Title: WeChatPublicAccountProperties
 * @Package: com.soyunn.config
 * @Description:
 * @Date 2019/8/19 15:13
 * @Version 1.0
 **/
@Data
@ConfigurationProperties(prefix = "weChat.public.account")
public class WeChatPublicAccountProperties {
    /**
     * 微信公众号appID:wxb1b022255b52bb30
     **/
    private String appId;
    /**
     * 微信公众号appsecret :0a0f040710d5e0d36d42e1110f16748e
     **/
    private String appsecret;
}

3、配置业务类,具体需要实现功能,这里就是简单的推送信息

package com.soyunn.service;

import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;

/**
 * @Author: AaronNg
 * @Title: PushMessageService
 * @Package: com.soyunn.service
 * @Description: 推送小心接口
 * @Date 2019/8/19 15:38
 * @Version 1.0
 **/
public class PushMessageService {

    /**
     * 微信公众号appID : wxb1b022255b52bb30
     **/
    private String appId;
    /**
     * 微信公众号appsecret:0a0f040710d5e0d36d42e1110f16748e
     **/
    private String appsecret;


    /**
     *  推送消息
     * @author: AaronNg
     * @param message
     * @return: void
     * @throws
     * @date: 15:55 2019/8/19
     **/
    public void pushMessage(WxMpTemplateMessage message) throws Exception{
        //1,配置
        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
        wxStorage.setAppId(appId);
        wxStorage.setSecret(appsecret);
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxStorage);
        wxMpService.getTemplateMsgService().sendTemplateMsg(message);
    }


    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getAppsecret() {
        return appsecret;
    }

    public void setAppsecret(String appsecret) {
        this.appsecret = appsecret;
    }

    public PushMessageService(String appId, String appsecret) {
        this.appId = appId;
        this.appsecret = appsecret;
    }

    public PushMessageService() {
    }
}

4、自动配置类,这里是重点

package com.soyunn.config;

import com.soyunn.properties.WeChatPublicAccountProperties;
import com.soyunn.service.PushMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Author: AaronNg
 * @Title: WeChatPublicAccountAutoConfiguration
 * @Package: com.soyunn.config
 * @Description: 自动配置
 * @Date 2019/8/19 15:13
 * @Version 1.0
 **/
@Configuration//开启配置
@EnableConfigurationProperties(WeChatPublicAccountProperties.class)//开启使用映射实体对象
@ConditionalOnClass(PushMessageService.class)//存在PushMessageService时初始化该配置类
@ConditionalOnProperty//存在对应配置信息时初始化该配置类
        (prefix = "weChat.public.account",//存在配置前缀hello
                value = "enabled",//开启
                matchIfMissing = true)//缺失检查
public class WeChatPublicAccountAutoConfiguration {

    //application.properties配置文件映射前缀实体对象
    @Autowired
    private WeChatPublicAccountProperties properties;

    /**
     * 根据条件判断不存在PushMessageService时初始化新bean到SpringIoc
     * @return
     */
    //创建PushMessageService实体bean
    @Bean
    //缺失PushMessageService实体bean时,初始化PushMessageService并添加到SpringIoc
    @ConditionalOnMissingBean(PushMessageService.class)
    public PushMessageService pushService(){
        System.out.println("appId:"+properties.getAppId()+",secret:"+ properties.getAppsecret());
        return new PushMessageService(properties.getAppId(), properties.getAppsecret());
    }

}

最后一步,在resources/META-INF/下创建spring.factories文件,并添加如下内容:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.soyunn.config.WeChatPublicAccountAutoConfiguration

这样就实现了一个starter了,至于怎么使用,就和普通的引入其他的starter一样,

引入maven依赖

<!--微信公众号推送-->
<dependency>
   <groupId>com.soyunn</groupId>
   <artifactId>wechatpublicaccount-spring-boot-starter</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>

然后在application.properties中配置需要的参数

#配置自定义starter参数
weChat.public.account.appId=公众号appid
weChat.public.account.appsecret=公众号密钥

注入你的那个业务类

@Autowired
PushMessageService pushMessageService;

然后调用即可

public void pushMessage(String[] to, String subject, String content) throws Exception {

    List<WxMpTemplateData> wxMpTemplateData = Arrays.asList(
            new WxMpTemplateData("first",subject),
            new WxMpTemplateData("keyword1",content),
            new WxMpTemplateData("keyword2",content)
    );
    List<String> openIdList;
    if(to == null || to.length == 0){
        //拉取关注着列表,推送所有人
        String accessToken = stringRedisTemplate.opsForValue().get("access_token");
        if(StringUtils.isBlank(accessToken)){
            //https请求方式: GET    获取access_token接口
            //https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
            AccessToken token = WeiXinUtils.getAccessToken(appid, secret);
            if(null != token){
                stringRedisTemplate.opsForValue().set("access_token", token.getToken(), token.getExpireIn() - 900L, TimeUnit.SECONDS);
                accessToken = token.getToken();
            }
        }
        openIdList = WeiXinUtils.getOpenIdList(accessToken, "");
    }else {
        openIdList = Arrays.asList(to);
    }
    if(CollectionUtils.isNotEmpty(openIdList)){
        for(String openId : openIdList){
            //2,推送消息
            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(openId)//要推送的用户openid
                    .templateId(tempId)//模版id
                    .data(wxMpTemplateData)
                    .build();
            this.pushMessage(templateMessage);
        }
    }
}

代码不全,只是为了记录下,方便以后有用到,也希望能给大家带来一些借鉴的意义。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值