观察者模式+AOP 代码示例

背景

当经纪人创建客户时,需要给对应的经纪人增加战报信息。在代码层面上,客源的相关类只针对客源数据表操作。而战报信息包含了多种业务统计数据,客源只是其中统计的部分数据。鉴于两者相对独立,且客源的战报信息会有所修改。因此,采用AOP+观察者模式构建代码

代码

定义一个注解,用于AOP拦截

/**
 * 战报注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.ParaMETER})
@Documented
public @interface AchievementAnnotation {

    OperateEnum operate() default OperateEnum.ADD;

    enum OperateEnum{
        ADD,UPDATE,DELETE
    }
}

定义AOP,用户获取数据,并转发给观察者

/**
 * 战报AOP
 */
@Aspect
@Component
public class AchievementAop {

    /**
     * 战报观察者列表
     */
    private List<AchievementObserver> observerList;

    public AchievementAop() {
        this.observerList = new ArrayList<>();
    }

    public List<AchievementObserver> getobserverList() {
        return observerList;
    }

    public void setobserverList(List<AchievementObserver> observerList) {
        if (null != this.observerList)
            this.observerList.addAll(observerList);
        this.observerList = observerList;
    }

    /**
        *注入客源的观察者
        */
    @Autowired
    public void setCustomerAchievementObserver(CustomerAchievementObserver customerAchievementObserver) {
        getobserverList().add(customerAchievementObserver);
    }

    @pointcut("@annotation(com.pretang.cloud.aop.AchievementAnnotation)")
    private void pointcut() {
    }

    @AfterReturning(pointcut = "pointcut()", returning = "retVal")
    public void after(JoinPoint joinPoint, Object retVal) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetmethod = methodSignature.getmethod();
        AchievementAnnotation annotation = targetmethod.getAnnotation(AchievementAnnotation.class);
        AchievementAnnotation.OperateEnum operateEnum = annotation.operate();
        for (AchievementObserver observer : observerList) {
            if (observer.isSupport(retVal))
                observer.execute(retVal);
        }
    }
}

定义观察者通用接口

/**
 * 战报信息观察者接口
 * @param <T>
 */
public interface AchievementObserver<T> {

    /**
     * 是否支持该对象
     * @param obj
     * @return
     */
    boolean isSupport(Object obj);

    /**
     * 操作业务数据
     * @param t
     * @throws RuntimeException
     */
    void execute(T t) throws RuntimeException;
}

客源观察者

/**
 * 客源信息的观察者
 */
@Component
public class CustomerAchievementObserver implements AchievementObserver<CustomerBase> {

    @Autowired
    private CustomerRpcService customerRpcService;

    @Override
    public boolean isSupport(Object obj) {
        return obj instanceof CustomerBase;
    }

    @Override
    public void execute(CustomerBase customerBase) throws RuntimeException {
            // 实际业务处理
        customerRpcService.saveAchievement(customerBase.getAgentUserId(), "ADD_CUSTOMER", customerBase.getId());
    }
}

相关文章

蚂蚁庄园小课堂2024年6月29日答案是什么?进入支付宝一起饲养...
谷歌小恐龙怎么调出来,我们将连接电脑的网络拔掉或者禁用网...
蚂蚁庄园小课堂2024年6月22日答案是什么?每天蚂蚁庄园小课堂...
火绒为什么不建议大家用,火绒对于用户的要求比较高,查杀病...
百度网盘电脑版订阅的分享在哪?百度网盘电脑版订阅的分享在什...
notepad怎么替换换行符,打开notepad++软件,点击菜单栏的视...