【仅供内部供应商使用,不提供对外解答和培训】

一、特殊名词介绍

二、背景、场景介绍

该接口是产品新开的接口,功能与EmailSendProvider相似,不过也有区别。EmailServiceProvider接口只能对产品本身的邮件发送逻辑进行替换。

【注】能选用EmailServiceProvider接口的情况下就不要使用EmailSendProvider。【具体原因下文会介绍】

三、接口介绍

EmailServiceProvider.java
package com.fr.stable.fun;

import com.fr.stable.email.EmailAttachmentProvider;
import com.fr.stable.fun.mark.Selectable;

import javax.mail.MessagingException;

/**
 * @author Cloud.Liu
 * @version 10.0
 * Created by Cloud.Liu on 2020/5/20
 */
public interface EmailServiceProvider extends Selectable {

    int CURRENT_LEVEL = 1;

    String XML_TAG = "EmailServiceProvider";

    /**
     * 发送邮件
     *
     * @param toAddress       收件人地址
     * @param ccAddress       抄送地址
     * @param bccAddress      密送地址
     * @param fromAddress     发件人地址
     * @param subject         主题
     * @param bodyContent     正文
     * @param attaches        附件
     * @param format          格式
     * @param contentAttaches 邮件正文显示的附件
     * @throws MessagingException 异常
     */
    void send(String toAddress, String ccAddress, String bccAddress, String fromAddress, String subject, String bodyContent, EmailAttachmentProvider[] attaches, String format, EmailAttachmentProvider[] contentAttaches) throws MessagingException;
}


四、支持版本

产品线

版本

支持情况

备注

FR10.0支持
BI5.1.3支持

五、插件注册

plugin.xml
<extra-core>
        <EmailServiceProvider class="your class name"/>
</extra-core>

六、原理说明

package com.fr.base;

...

@EnableMetrics
public class EmailManager extends UniqueKey implements EmailManagerProvider, EmailServiceProvider {

    ...

    /**
     * 发送邮件,处理走默认还是{@link EmailServiceProvider}插件接口的逻辑
     *
     * @param toAddress       收件人地址
     * @param ccAddress       抄送地址
     * @param bccAddress      密送地址
     * @param fromAddress     发件人地址
     * @param subject         主题
     * @param bodyContent     正文
     * @param attaches        附件
     * @param format          格式
     * @param contentAttaches 邮件正文显示的附件
     * @throws MessagingException 异常
     * @date 2019-10-10
     */
    @Override
    public void send(String toAddress, String ccAddress, String bccAddress, String fromAddress, String subject, String bodyContent, EmailAttachmentProvider[] attaches, String format, EmailAttachmentProvider[] contentAttaches) throws MessagingException {
        Set<EmailServiceProvider> providers = getEmailServiceProvider();
        if (providers.isEmpty()) {
            sendEmail(toAddress, ccAddress, bccAddress, fromAddress, subject, bodyContent, attaches, format, contentAttaches);
        } else {
            boolean sent = false;
            for (EmailServiceProvider provider : providers) {
                if (provider.selector().accept(ObjectHolder.wrap(toAddress))) {
                    provider.send(toAddress, ccAddress, bccAddress, fromAddress, subject, bodyContent, attaches, format, contentAttaches);
                    sent = true;
                }
            }
            if (!sent) {
                FineLoggerFactory.getLogger().error("No email services accept this email: " + subject + " to " + toAddress + ".");
            }
        }
    }

   	...

    private Set<EmailServiceProvider> getEmailServiceProvider() {
        ExtraClassManagerProvider provider = PluginModule.getAgent(PluginModule.ExtraCore);
        if (provider != null) {
            return provider.getArray(EmailServiceProvider.XML_TAG);
        } else {
            return new HashSet<EmailServiceProvider>();
        }
    }

	...
}


七、特殊限制说明

EmailSendProvider与EmailServiceProvider相比,功能更强大,触发时机更早,可以选择覆盖产品邮件发送(与EmailServiceProvider接口功能相似)或者仅仅时监听邮件发送请求执行(执行完毕后,依然会执行产品标准的邮件发送功能)。也就是说如果使用了EmailSendProvider的替换方式,那么EmailServiceProvider接口基本就是会失效的。但是EmailSendProvider本身也存在缺陷,就是如果一个系统有多个EmailSendProvider接口实例,都采用了监听模式(不直接替换),那么一个邮件发送请求就会被触发多次,最终多次发送邮件。

所以选择的依据是,能使用EmailServiceProvider的场景就尽可能使用EmailServiceProvider场景。如果目标系统已经有一个EmailSendProvider接口实现的实例了,先确定该实例是否是拦截模式、如果是拦截模式,那么就只能选择EmailSendProvider接口实现,否则应使用EmailServiceProvider接口



八、常用链接

demo地址:demo-email-service-provider


九、开源案例

免责声明:所有文档中的开源示例,均为开发者自行开发并提供。仅用于参考和学习使用,开发者和官方均无义务对开源案例所涉及的所有成果进行教学和指导。禁止用于任何商业用途,若作为商用一切后果责任由使用者自行承担。

open-JSD-8153


  • No labels