AOP注解策略模式实例(策略+抽象)

本文介绍了策略模式的结构,包括环境(Context)、抽象策略(Strategy)和具体策略(ConcreteStrategy)角色。通过一个示例展示了如何在Java中实现策略模式,包括切面注解、扫描工具类、接口定义、抽象类以及具体的实现类。同时,还展示了如何通过上下文类来获取和使用不同的策略实现,以处理不同来源的商机匹配任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

策略模式的结构
  策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理。策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是:“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。下面就以一个示意性的实现讲解策略模式实例的结构。

  这个模式涉及到三个角色:

  ●  环境(Context)角色:持有一个Strategy的引用。

  ●  抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

  ●  具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

源码如下:
 

1.切面

import java.lang.annotation.*;

/**
 * @ClassName AppSource
 * @Description 端来源
 * @Author zhangs
 * @email 853632587@qq.com
 * @Date 2021/9/6 19:21
 * @Version  1.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface AppSource {
    //AppSourceEnum
    byte value();
}

  2.扫描工具类

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;


public class SpringClassScanner {


    /**
     * 获取包下所有,标注annotationType 的类
     * @param scanPackage 包名
     * @param annotationType 注解类型
     * @return 满足要求的class set集合
     */
    public static Set<Class<?>> findAnnotatedClasses(String scanPackage, Class<? extends Annotation> annotationType) {
        ClassPathScanningCandidateComponentProvider provider = createComponentScannerIncludeAnnotation(annotationType);
        return getClass(scanPackage, provider);
    }


    /**
     * 获取所有继承clazz的class
     * @param scanPackage 包名
     * @param clazz 父类class
     * @return 满足要求的class set集合
     */
    public static Set<Class<?>> findAssignableClass(String scanPackage, Class<?> clazz) {
        ClassPathScanningCandidateComponentProvider provider = createComponentScannerIncludeAssignableType(clazz);
        return getClass(scanPackage, provider);
    }

    private static ClassPathScanningCandidateComponentProvider createComponentScannerIncludeAnnotation(Class<? extends Annotation> annotationType) {
        // Don't pull default filters (@Component, etc.):
        ClassPathScanningCandidateComponentProvider provider
                = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AnnotationTypeFilter(annotationType));
        return provider;
    }


    private static ClassPathScanningCandidateComponentProvider createComponentScannerIncludeAssignableType(Class<?> clazz) {
        // Don't pull default filters (@Component, etc.):
        ClassPathScanningCandidateComponentProvider provider
                = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AssignableTypeFilter(clazz));
        return provider;
    }

    private static Set<Class<?>> getClass(String scanPackage, ClassPathScanningCandidateComponentProvider provider) {
        Set<Class<?>> classSet = new HashSet<>();
        for (BeanDefinition beanDef : provider.findCandidateComponents(scanPackage)) {
            try {
                Class<?> cl = Class.forName(beanDef.getBeanClassName());
                classSet.add(cl);
            } catch (ClassNotFoundException e) {
                //IGNORE
            }

        }
        return classSet;
    }
}

 3.接口类 

import com.xxx.match.message.event.SalesMatchEvent;

import java.io.IOException;

/**
 * @ClassName MatchResourceHandler 
 * @Description No such property: code for class: Script1
 * @Author zhangs
 * @email 853632587@qq.com
 * @Date 2021/9/6 18:37
 * @Version  1.0
 */
public interface MatchResourceHandler {

    /**
     * 处理商机原文(拆词)
     * @param event
     */
    void resourceMatchEvent(SalesMatchEvent event);
    /**
     * 写入商机
     * @param event
     */
    void salesMatchInsertEvent(SalesMatchEvent event) throws IOException;
    /**
     * 发送商机
     * @param event
     */
    void SsalesMatchSendEvent(SalesMatchEvent event);

}

 4.抽象类(使用公用代码块)

/**
 * @ClassName AbstractMatchResourceHandler 
 * @Description 抽象商机结果集匹配处理
 * @Author zhangs
 * @email 853632587@qq.com
 * @Date 2021/9/6 18:40
 * @Version 1.0
 */
public abstract class AbstractMatchResourceHandler implements MatchResourceHandler {


  //公用代码块



}

 5.实现接口类

import com.alibaba.fastjson.JSON;
import com.xxx.account.sdk.domain.Staff;
import com.xxx.common.sdk.annotation.AppSource;
import com.xxx.common.sdk.constant.BaseConstant;
import com.xxx.common.sdk.redis.JedisTemplate;
import com.xxx.common.sdk.util.DateUtil;
import com.xxx.common.sdk.util.LogUtil;
import com.xxx.match.common.constant.Constant;
import com.xxx.match.message.event.SalesMatchEvent;
import com.xxx.match.message.strategy.ResourceMatchHandlerContext;
import com.xxx.match.rpc.AccountRpc;
import com.xxx.match.service.SalesMatchService;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Objects;

/**
 * @ClassName QdMatchResourceHandler 
 * @Description 企点商机结果集匹配处理
 * @Author zhangs
 * @email 853632587@qq.com
 * @Date 2021/9/6 18:40
 * @Version 1.0
 */
@Component
@AppSource(1)//AppSourceEnum
public class QdMatchResourceHandler extends AbstractMatchResourceHandler {

     @ApiOperation("处理商机原文-拆词")
    @Override
    public void resourceMatchEvent(SalesMatchEvent event) {

       //业务 代码块

    }



    @ApiOperation("写入商机")
    @Override
    public void salesMatchInsertEvent(SalesMatchEvent event) throws IOException {

        //业务 代码块

    }



    @ApiOperation("发送商机")
    @Override
    public void SsalesMatchSendEvent(SalesMatchEvent event) {

        //业务 代码块

    }

}

 6.实现上下文

import com.xxx.common.sdk.annotation.AppSource;
import com.xxx.common.sdk.util.ApplicationContextUtil;
import com.xxx.common.sdk.util.SpringClassScanner;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName MatchResourceHandlerContext 
 * @Description 商机匹配策略模式
 * @Author zhangs
 * @email 853632587@qq.com
 * @Date 2021/9/6 19:31
 * @Version  1.0
 */
@Component
public class MatchResourceHandlerContext {

    private static final String HANDLER_PACKAGE = "com.xxx.match.message.chain.handler.strategy";

    private Map<Byte, Class<?>> handlerMap = new HashMap<>();

    @PostConstruct
    public void init() {
        Set<Class<?>> handlerClass = SpringClassScanner.findAnnotatedClasses(HANDLER_PACKAGE, AppSource.class);
        for (Class<?> aClass : handlerClass) {
            AppSource appSource = aClass.getAnnotation(AppSource.class);
            byte value = appSource.value();
            handlerMap.put(value, aClass);
        }
    }

    public MatchResourceHandler getHandler(byte appSource) {
        Class<?> handlerClass = handlerMap.get(appSource);
        return (MatchResourceHandler) ApplicationContextUtil.getBean(handlerClass);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值