工厂模式结合注解与枚举实现
- 乐器类型枚举类
- 乐器注解类
- Service 层接口
- Service接口实现类
- 1 通用实现类
- 2 钢琴实现类
- 3 吉他实现类
- 4 鼓实现类
- 5 喇叭实现类
- 工厂类
- 方式一:实现 ApplicationContextAware
- 方式二:构造器+@Autowired注解
- 测试方法
此demo以乐器为例,实现获取service层实现类的工厂,利用了SpringBean的注册原理。相同接口多个不同实现在工作中比较常见,所以这种使用也是最基础的。
逻辑:通过在实现类上标注注解,程序启动时将实现类放入map中,key为注解中的枚举值,value为Bean,程序需使用的地方直接从map中获取即可。
此例中注解为乐器类枚举值,通常工作开发过程中,InstrumentType以参数传递,事先并不可知,根据这个参数选择对应的实现并调用方法。
乐器类型枚举类
/**
* @author : wind-myf
* @desc : 乐器类型枚举
*/
public enum InstrumentTypeEnum {
GENERAL("GENERAL","通用乐器"),
PIANO("PIANO","钢琴"),
GUITAR("GUITAR","吉他"),
HORN("HORN","喇叭"),
DRUM("DRUM","鼓");
private String code;
private String desc;
InstrumentTypeEnum(String code,String desc){
this.code = code;
this.desc = desc;
}
public String getCode() {
return code;
}
public String getDesc() {
return desc;
}
}
乐器注解类
/**
* 乐器类注解
* @author wind_myf
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface InstrumentAnnotation {
String instrumentType() default "GENERAL";
}
Service 层接口
/**
* @author : wind-myf
* @desc : 乐器类 Service
*/
public interface InstrumentService {
/**
* 弹奏乐器
* @param userName 用户名
* @return String
*/
String playInstrument(String userName);
}
Service接口实现类
1 通用实现类
/**
* @author : wind-myf
* @desc : 通用实现类
*/
@Service("generalService")
@InstrumentAnnotation(instrumentType = "GENERAL")
public class GeneralServiceImpl implements InstrumentService {
@Override
public String playInstrument(String userName) {
// 模拟业务逻辑
String result = userName + "play the general instrument";
System.out.println(userName + "play the general instrument - " + System.currentTimeMillis());
return result;
}
}
2 钢琴实现类
/**
* @author : wind-myf
* @desc : 钢琴实现类
*/
@Service("pianoService")
@InstrumentAnnotation(instrumentType = "PIANO")
public class PianoServiceImpl implements InstrumentService {
@Override
public String playInstrument(String userName) {
// 模拟业务逻辑
String result = userName + "play the piano";
System.out.println(userName + "play the piano - " + System.currentTimeMillis());
return result;
}
}
3 吉他实现类
/**
* @author : wind-myf
* @desc : 吉他实现类
*/
@Service("guitarService")
@InstrumentAnnotation(instrumentType = "GUITAR")
public class GuitarServiceImpl implements InstrumentService {
@Override
public String playInstrument(String userName) {
// 模拟业务逻辑
String result = userName + "play the guitar";
System.out.println(userName + "play the guitar - " + System.currentTimeMillis());
return result;
}
}
4 鼓实现类
/**
* @author : wind-myf
* @desc : 鼓实现类
*/
@Service("drumService")
@InstrumentAnnotation(instrumentType = "DRUM")
public class DrumServiceImpl implements InstrumentService {
@Override
public String playInstrument(String userName) {
// 模拟业务逻辑
String result = userName + "play the drum";
System.out.println(userName + "play the drum - " + System.currentTimeMillis());
return result;
}
}
5 喇叭实现类
/**
* @author : wind-myf
* @desc : 喇叭实现类
*/
@Service("hornService")
@InstrumentAnnotation(instrumentType = "HORN")
public class HornServiceImpl implements InstrumentService {
@Override
public String playInstrument(String userName) {
// 模拟业务逻辑
String result = userName + "play the horn";
System.out.println(userName + "play the horn - " + System.currentTimeMillis());
return result;
}
}
工厂类
方式一:实现 ApplicationContextAware
/**
* @author : wind-myf
* @desc : 乐器工厂 类,实现 ApplicationContextAware方式
*/
@Component
public class InstrumentFactory implements ApplicationContextAware {
private static HashMap<String, InstrumentService> instrumentServiceMap = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
// 获取包含音乐注解的类
Map<String, Object> beansWithAnnotationMap = applicationContext.getBeansWithAnnotation(InstrumentAnnotation.class);
for (Object bean : beansWithAnnotationMap.values()) {
InstrumentAnnotation annotation = bean.getClass().getAnnotation(InstrumentAnnotation.class);
if (annotation == null){
continue;
}
System.out.println(bean);
instrumentServiceMap.put(annotation.instrumentType(), (InstrumentService) bean);
}
}
public static InstrumentService getInstrumentService(String instrumentType){
return instrumentServiceMap.get(instrumentType);
}
}
方式二:构造器+@Autowired注解
/**
* @author : wind-myf
* @desc : 乐器工厂 类 (使用构造器方式)
*/
@Component
public class InstrumentFactoryNew{
private static HashMap<String, InstrumentService> instrumentServiceMap = new HashMap<>();
@Autowired
public InstrumentFactoryNew(List<InstrumentService> instrumentServices){
for (InstrumentService instrumentService : instrumentServices) {
InstrumentAnnotation annotation = instrumentService.getClass().getAnnotation(InstrumentAnnotation.class);
if (annotation == null){
continue;
}
System.out.println(instrumentService);
instrumentServiceMap.put(annotation.instrumentType(),instrumentService);
}
}
public static InstrumentService getInstrumentService(String instrumentType){
return instrumentServiceMap.get(instrumentType);
}
}
测试方法
@Test
void testInstrumentFactory(){
InstrumentService instrumentService = InstrumentFactory.getInstrumentService(InstrumentTypeEnum.PIANO.getCode());
Assert.isTrue(instrumentService != null,"获取工厂类失败");
String playInstrument = instrumentService.playInstrument("张三");
System.out.println("playInstrument = " + playInstrument);
}
@Test
void testInstrumentFactoryNew(){
InstrumentService instrumentService = InstrumentFactoryNew.getInstrumentService(InstrumentTypeEnum.PIANO.getCode());
Assert.isTrue(instrumentService != null,"获取工厂类失败");
String playInstrument = instrumentService.playInstrument("李四");
System.out.println("playInstrument = " + playInstrument);
}
以上代码可直接运行,根据实际需求替换代码即可。