1、需求
乐企文件生成工程中,有不同的票种,每个票种对应的实现类不一样,现在希望通过一个类就能管理所有的票种实现类,不用每次都使用@Autowired或者 @Resource逐个注入。
2、做法
创建一个DataComponent,实现Spring中的
ApplicationContextAware
以及PriorityOrdered
接口,代码如下:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.PriorityOrdered;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* User: yanjun.hou
* Date: 2024/12/10 17:51
* Description:获取指定的上下文组件
*/
@Component
public class DataComponent implements ApplicationContextAware, PriorityOrdered {
private static ApplicationContext applicationContext;
public static final Map<Class, Object> dataTableMap = new ConcurrentHashMap<>();
/**
* ApplicationContextAware 需要获取应用上下文
*
* @param applicationContext 应用上下问
* @throws BeansException bean 异常
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
DataComponent.applicationContext = applicationContext;
}
/**
* PriorityOrdered 初始化优先级(赋最小值,最先加载)
*
* @return 优先级
*/
@Override
public int getOrder() {
return PriorityOrdered.HIGHEST_PRECEDENCE;
}
//@SuppressWarnings("all") 作用:忽略警告
@SuppressWarnings("all")
public static <T> T of(Class<T> clazz) {
T instance = (T) dataTableMap.get(clazz);
if (null != instance) {
return instance;
}
// 当获取不到bean时,将bean通过class的方式添加到
dataTableMap.put(clazz, bean(clazz));
return (T) dataTableMap.get(clazz);
}
/**
* 通过bean的名称加载bean
*
* @param beanName bean名称
* @param <T> bean范型
* @return bean
*/
@SuppressWarnings("all")
private static <T> T bean(String beanName) {
return (T) applicationContext.getBean(beanName);
}
@SuppressWarnings("all")
private static <T> T bean(Class clazz) {
return (T) applicationContext.getBean(clazz);
}
}
3、用法
package com.lq.invoice.factory;
import com.lq.invoice.service.file.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
/**
* User: yanjun.hou
* Date: 2024/10/19 19:15
* Description:
*/
@Component
public class InvoiceFileFactory {
public InvoiceFileService getInvoiceFileService(String tdys) {
if (StringUtils.isEmpty(tdys)) {
return DataComponent.of(BaseInvoiceFileServiceImpl.class);
}
switch (tdys) {
case "04":
return DataComponent.of(GoodsTransportInvoiceFileImpl.class);//货物运输
case "03":
return DataComponent.of(BuildingInvoiceFileImpl.class);//建筑服务
case "05":
return DataComponent.of(RealPropertySellInvoiceFileImpl.class);//不动产销售 暂不支持 后续开发
case "06":
return DataComponent.of(RealPropertyRentInvoiceFileImpl.class);//不动产租赁
case "09":
return DataComponent.of(TravellerTransportInvoiceFileImpl.class);//旅客运输
default:
return DataComponent.of(BaseInvoiceFileServiceImpl.class);
}
}
}
OK,通过
DataComponent.of(xxx.class)
就能实现需要什么组件获取什么组件的需求了。