静态工厂加策略模式(spring注解实现)
根据spring容器原理(map),吧bean和code对应起来,然后根据不同的code 去拿具体的bean
抽象方法
/**
* @author: craywen
* @date: 2021-02-23 17:47
* @desc: 执行
*/
public abstract class AbstractCommentSaveExtension {
/**
*
* @author craywen
* @Description : 执行;
* @date 2021/2/23 17:55
* @return: void
* @version 2.0.0
*/
public abstract void exec();
}
策略模式注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: craywen
* @date: 2021-02-23 17:43
* @desc:
*/
@Target(ElementType.TYPE) // 作用类、接口、枚举
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface LcwSource {
int code() default 0;
}
bean 工具类(SpringContextUtils)
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author: craywen
* @date: 2021-02-23 17:48
* @desc:
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
/**
* @Author: wx
* @Desc: 根据class类型返回相应的所有bean
* @Date: 1:34 PM 2019/10/17
* @param: c
* @return: java.util.Map<java.lang.String,V>
**/
public static <V> Map<String,V> getBeanMapByClass(Class<V> c){
//根据接口类型返回相应的所有bean
return applicationContext.getBeansOfType(c);
}
}
静态工厂
- 工厂工具类
import com.lcw.design.AbstractCommentSaveExtension;
import com.lcw.design.utils.BuildStaticFactoryUtils;
import com.lcw.pojo.AbstractCollectionList;
import java.util.Map;
/**
* @author: craywen
* @date: 2021-02-23 17:47
* @desc:
*/
public class StaticFactoryUtils {
private static final Map<Integer, AbstractCollectionList> collectionListMap;
private static final Map<Integer,Class<AbstractCommentSaveExtension>> commentSaveExtensionKeyMap;
static {
collectionListMap = BuildStaticFactoryUtils.buildFactory(AbstractCollectionList.class);
commentSaveExtensionKeyMap = BuildStaticFactoryUtils.buildSpringBeanKeyMapPing(AbstractCommentSaveExtension.class);
}
private StaticFactoryUtils(){
System.out.println("拒绝反射创建对象");
}
/**
* @Author: wx
* @Desc: 获取收藏集合列表静态工厂
* @Date: 4:25 PM 2019/10/17
* @param:
* @return: java.util.Map<java.lang.Integer,com.hcp.user.design.collection.list.AbstractCollectionList>
**/
public static Map<Integer, AbstractCollectionList> getCollectionListMap() {
return collectionListMap;
}
/**
*
* @author craywen
* Description : 获取指定的bean
* @date 2021/2/25 14:25
* @param commentType:
* @return: com.lcw.design.AbstractCommentSaveExtension
* @version 2.0.0
*/
public static AbstractCommentSaveExtension getCommentSaveExtension(Integer commentType){
Class<AbstractCommentSaveExtension> key = commentSaveExtensionKeyMap.get(commentType);
return SpringContextUtils.getBean(key);
}
}
-
静态工厂
import com.lcw.annotation.LcwSource; import com.lcw.utils.SpringContextUtils; import org.omg.CORBA.SystemException; import org.springframework.util.CollectionUtils; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.Map; /** * @author: craywen * @date: 2021-02-23 17:49 * @desc: */ public class BuildStaticFactoryUtils { private BuildStaticFactoryUtils() { System.out.println("拒绝反射创建对象"); } /** * @Author: wx * @Desc: 构建静态工厂 * @Date: 2:11 PM 2019/10/17 * @param: aClass * @return: java.util.Map<java.lang.Integer , V> **/ public static <V> Map<Integer, V> buildFactory(Class<V> aClass) { if (aClass == null) { return new HashMap<>(0); } Map<String, V> beanMapByClass = SpringContextUtils.getBeanMapByClass(aClass); if (CollectionUtils.isEmpty(beanMapByClass)) { return new HashMap<>(0); } Map<Integer, V> interfaceImplMap = new HashMap<>(beanMapByClass.size()); beanMapByClass.values().forEach(bean -> { Class<?> bClass = bean.getClass(); //验证不是接口与抽象类 if (!bClass.isInterface() && !Modifier.isAbstract(bClass.getModifiers())) { LcwSource hcpSerialNumber = bClass.getAnnotation(LcwSource.class); //验证有没有加入SerialNumber注解 if (hcpSerialNumber != null) { //装载进容器 interfaceImplMap.put(hcpSerialNumber.code(), bean); } } }); return interfaceImplMap; } /** * @Author: wx * @Desc: 构建spring Bean key map * @Date: 2:11 PM 2019/10/17 * @param: aClass * @return: java.util.Map<java.lang.Integer , Class> **/ public static <V> Map<Integer, Class<V>> buildSpringBeanKeyMapPing(Class<V> aClass) { if (aClass == null) { return new HashMap<>(0); } Map<String, V> beanMapByClass = SpringContextUtils.getBeanMapByClass(aClass); if (CollectionUtils.isEmpty(beanMapByClass)) { return new HashMap<>(0); } Map<Integer, Class<V>> springBeanKeyMap= new HashMap<>(beanMapByClass.size()); beanMapByClass.values().forEach(bean -> { Class bClass = bean.getClass(); //验证不是接口与抽象类 if (!bClass.isInterface() && !Modifier.isAbstract(bClass.getModifiers())) { LcwSource hcpSerialNumber = (LcwSource) bClass.getAnnotation(LcwSource.class); //验证有没有加入SerialNumber注解 if (hcpSerialNumber != null) { //装载进容器 springBeanKeyMap.put(hcpSerialNumber.code(), bClass); } } }); return springBeanKeyMap; }
抽象实现类(多策略,多个实现类)
- CommentSaveA
import com.lcw.annotation.LcwSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author: craywen
* @date: 2021-02-23 17:57
* @desc:
*/
@Service
@LcwSource(code = 1)
@Slf4j
public class CommentSaveA extends AbstractCommentSaveExtension{
@Override
public void exec() {
System.out.println("CommentSaveA---> exec");
log.error("CommentSaveA---> exec");
}
}
- CommentSaveB
import com.lcw.annotation.LcwSource;
import org.springframework.stereotype.Service;
/**
* @author: craywen
* @date: 2021-02-23 17:59
* @desc:
*/
@Service
@LcwSource(code = 2)
public class CommentSaveB extends AbstractCommentSaveExtension{
@Override
public void exec() {
System.out.println("CommentSaveB---> exec");
}
}
测试方法
import com.lcw.design.AbstractCommentSaveExtension;
import com.lcw.pojo.AbstractCollectionList;
import com.lcw.utils.StaticFactoryUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Map;
/**
* @author: craywen
* @date: 2021-02-23 18:02
* @desc:
*/
@SpringBootTest
@RunWith(SpringRunner.class)
@ComponentScan(basePackages = {
"com.lcw.*"})
public class TestA {
@Test
public void testSingle(){
int code =1;
AbstractCommentSaveExtension commentSaveExtension = StaticFactoryUtils.getCommentSaveExtension(code);
commentSaveExtension.exec();
}
}
- 输出
CommentSaveA---> exec
2021-02-26 10:39:41.610 ERROR 28564 --- [ main] com.lcw.design.CommentSaveA : CommentSaveA---> exec