Spring Autowired扩展策略模式

背景

策略模式在实际开发中使用非常频繁的设计模式;

通常都是写完策略类后,还要专门写一个类进行策略分发,比较繁琐;

spring中利用@Autowired注解,可以支持自动注入list、map类型

@Autowired
private Map map;

map的key,是实例bean的beanName;

往往在实际使用过程中,策略key是业务场景类型还不是beanName;

实现

基于注解的方式完成策略模式

通过spring BeanPostProcessor初始化回调,支持自定义map key

show code:

StrategyPattern

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StrategyPattern {
}
StrategyKey
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StrategyKey {

    String value() default "";
}
StrategyDefault
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StrategyDefault {
}
StrategyMap
public class StrategyMap extends LinkedHashMap {

    @Override
    public V get(Object key) {
        V v = super.get(key);
        return Objects.isNull(v) ? super.get("StrategyDefault") : v;
    }
}

自定义StrategyInstantiationAwareBeanPostProcessor

@Component
public class StrategyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    public final static String HELLO_BIKE_PACKAGE = "hello";

    public String getScanPackageKeyword() {
        return HELLO_BIKE_PACKAGE;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        try {
            String packageName = Optional.of(bean)
                    .map(Object::getClass)
                    .map(Class::getPackage)
                    .map(Package::getName)
                    .orElse(null);
            if (!StringUtils.contains(packageName, getScanPackageKeyword())) {
                return bean;
            }
            Field[] declaredFields = bean.getClass().getDeclaredFields();
            for (Field declaredField : declaredFields) {
                StrategyPattern annotation = AnnotationUtils.findAnnotation(declaredField, StrategyPattern.class);
                if (annotation == null) {
                    continue;
                }
                if (declaredField.getType() == Map.class) {
                    ReflectionUtils.makeAccessible(declaredField);
                    Map strategyMap = (Map) ReflectionUtils.getField(declaredField, bean);
                    if (MapUtils.isEmpty(strategyMap)) {
                        log.warn("beanName:{},property:{}, strategy is null", beanName, declaredField.getName());
                        continue;
                    }
                    Map newMap = new StrategyMap<>();
                    for (Map.Entry entry : strategyMap.entrySet()) {
                        StrategyKey strategyKey = AnnotationUtils.findAnnotation(entry.getValue().getClass(), StrategyKey.class);
                        if (strategyKey == null) {
                            newMap.put(entry.getKey(), entry.getValue());
                        } else {
                            newMap.put(strategyKey.value(), entry.getValue());
                        }

                        if (AnnotationUtils.findAnnotation(entry.getValue().getClass(), StrategyDefault.class) != null) {
                            newMap.put("StrategyDefault", entry.getValue());
                        }
                    }
                    ReflectionUtils.setField(declaredField, bean, newMap);
                }
            }
        } catch (Exception e) {
            log.error("beanName:{}, strategy pattern init err ", beanName, e);
        }
        return bean;
    }
}

使用方式

public interface Test {

    String test();
}
@Component("Test1")
@StrategyDefault
public class Test1 implements Test {

    @Override
    public String test() {
        return "Test1";
    }
}
@Component
@StrategyKey("bean_test2")
public class Test2 implements Test{

    @Override
    public String test() {
        return "Test2";
    }
}
@Component
public class UserServiceImpl implements UserService {

    @Autowired
    @StrategyPattern
    private Map map;

    @Override
    @PostConstruct
    public UserDTO getUser() {
        UserDTO user = new UserDTO();
        user.setUserId(1L);
        user.setUserName("zhang san");
        user.setAge(18);
        System.err.println("==================================" + map.get("Test1").test());
        for (Map.Entry stringTestEntry : map.entrySet()) {
            System.out.println("key:::::::::::::" + stringTestEntry.getKey());
        }
        return user;
    }
}

你可能感兴趣的:(java,策略模式,spring,java)