├── GiftApplication.java
├── GiftFactory.java
├── bean
│ ├── GiftBean.java
│ └── ResultBean.java
├── constant
│ └── GiftConstant.java
└── gift
├── IGiftService.java
└── impl
├── GiftLotteryService.java
└── GiftLuckService.java
public interface IGiftService {
ResultBean sendGift(GiftBean giftBean);
}
@Component(GiftConstant.GIFT_LOTTERY)
public class GiftLotteryService implements IGiftService {
@Override
public ResultBean sendGift(GiftBean giftBean) {
System.out.println("发送抽奖礼物");
return new ResultBean(1000, "送抽奖礼物成功!");
}
}
@Component(GiftConstant.GIFT_LUCK)
public class GiftLuckService implements IGiftService {
@Override
public ResultBean sendGift(GiftBean giftBean) {
System.out.println("发送幸运礼物");
return new ResultBean(1000, "送幸运礼物成功!");
}
}
@Service
public class GiftFactory {
// 通过 Spring 注入(结果为 HashMap)
@Autowired
private Map<String, IGiftService> giftServiceMap;
public IGiftService getGiftService(String component) {
// System.out.println(giftServiceMap instanceof HashMap);
IGiftService giftService = giftServiceMap.get(component);
if (giftService == null) {
throw new RuntimeException("礼物类型未定义");
}
return giftService;
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class GiftFactoryTest {
@Autowired
GiftFactory giftFactory;
@Test
public void test() {
giftFactory.getGiftService(GiftConstant.GIFT_LUCK).sendGift(new GiftBean(1, "幸运礼物1", 100));
giftFactory.getGiftService(GiftConstant.GIFT_LOTTERY).sendGift(new GiftBean(2, "抽奖礼物2", 200));
}
}
├── VideoApplication.java
├── bean
│ └── VideoStreamAuditInfo.java
└── video
├── IVideoAuditService.java
├── factory
│ ├── IVideoAdapter.java
│ └── impl
│ ├── QNStreamAdapter.java
│ ├── UCStreamAdapter.java
│ └── XStreamAdapter.java
├── impl
│ └── VideoAuditServiceImpl.java
├── proxy
│ ├── VideoInvocationHandler.java
│ └── VideoProxy.java
└── stream
├── QNStream.java
├── UCStream.java
└── XStream.java
public interface IVideoAuditService {
/**
* 获取视频流审核结果
*/
VideoStreamAuditInfo getStreamAuditInfo(Integer sId);
}
@Component
public class VideoAuditServiceImpl implements IVideoAuditService {
@Autowired
// private QNStream qnStream;
private QNStream qnStream = new QNStream();
/**
* 返回视频流审核信息,如果不存在返回 null
*/
@Override
public VideoStreamAuditInfo getStreamAuditInfo(Integer sId) {
return qnStream.getQNStreamAuditInfo(sId);
}
}
@Component
public class QNStream {
private Map<Integer, VideoStreamAuditInfo> streamMap = new ConcurrentHashMap<>();
{
streamMap.put(100, new VideoStreamAuditInfo(100, "", 1));
}
/**
* 返回 QN 流审核信息,不存在返回 null
*/
public VideoStreamAuditInfo getQNStreamAuditInfo(int sId) {
return streamMap.get(sId);
}
}
@Component
public class UCStream {
private Map<Integer, VideoStreamAuditInfo> streamMap = new ConcurrentHashMap<>();
{
streamMap.put(200, new VideoStreamAuditInfo(200, "", 1));
}
/**
* 返回 UC 流审核信息,不存在返回 null
*/
public VideoStreamAuditInfo getUCStreamAuditInfo(int sId) {
return streamMap.get(sId);
}
}
@Component
public class XStream {
private Map<Integer, VideoStreamAuditInfo> streamMap = new ConcurrentHashMap<>();
{
streamMap.put(300, new VideoStreamAuditInfo(300, "", 0));
}
/**
* 返回 X 流审核信息,不存在返回 null
*/
public VideoStreamAuditInfo getXStreamAuditInfo(int sId) {
return streamMap.get(sId);
}
}
public interface IVideoAdapter {
VideoStreamAuditInfo getStreamAuditInfo(Integer sId);
}
@Component
public class QNStreamAdapter implements IVideoAdapter {
@Autowired
// private QNStream qnStream;
private QNStream qnStream = new QNStream();
@Override
public VideoStreamAuditInfo getStreamAuditInfo(Integer sId) {
return qnStream.getQNStreamAuditInfo(sId);
}
}
@Component
public class UCStreamAdapter implements IVideoAdapter {
@Autowired
// private UCStream ucStream;
private UCStream ucStream = new UCStream();
@Override
public VideoStreamAuditInfo getStreamAuditInfo(Integer sId) {
return ucStream.getUCStreamAuditInfo(sId);
}
}
@Component
public class XStreamAdapter implements IVideoAdapter {
@Autowired
// private XStream xStream;
private XStream xStream = new XStream();
@Override
public VideoStreamAuditInfo getStreamAuditInfo(Integer sId) {
return xStream.getXStreamAuditInfo(sId);
}
}
public class VideoInvocationHandler implements InvocationHandler {
private IVideoAdapter videoAdapter;
public VideoInvocationHandler(IVideoAdapter videoAdapter) {
this.videoAdapter = videoAdapter;
}
/**
* 调用传入的适配器 + method
* @param proxy 新建的代理类本身
* @param method 通过代理类调用的方法本身
* @param args 通过代理类调用的方法中的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 需调用方法的类与代理实现类不同
return IVideoAdapter.class.getMethod(method.getName(), getClazzByArgs(args)).invoke(videoAdapter, args);
}
private static Class<?>[] getClazzByArgs(Object[] args) {
Class<?>[] parameterTypes = new Class[args.length];
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof ArrayList) {
parameterTypes[i] = List.class;
continue;
}
if (args[i] instanceof LinkedList) {
parameterTypes[i] = List.class;
continue;
}
if (args[i] instanceof HashMap) {
parameterTypes[i] = Map.class;
continue;
}
if (args[i] instanceof TimeUnit){
parameterTypes[i] = TimeUnit.class;
continue;
}
parameterTypes[i] = args[i].getClass();
}
return parameterTypes;
}
}
public class VideoProxy {
/**
* 获取动态代理
* 可通过反编译看出:其实是重建一个继承了 Proxy 类的 $Proxy0 类,同时实现了传入的接口
* @param serviceClass 被代理类的 class 类
* @param videoAdapter 具体使用的类
* @return 动态代理对象
*/
public static <T> T getProxy(Class<T> serviceClass, IVideoAdapter videoAdapter) throws Exception {
/**
* 通过类加载器和接口确认代理哪个接口
* interfaces 被代理的类,它必须至少实现一个接口
* classLoader 类加载器,可用被代理类接口的类加载器(参考 MyBatis 源码 MapperProxyFactory)
*/
ClassLoader classLoader = serviceClass.getClassLoader();
Class<?>[] interfaces = serviceClass.getInterfaces();
// 具体实现代理方案
InvocationHandler invocationHandler = new VideoInvocationHandler(videoAdapter);
return (T)Proxy.newProxyInstance(classLoader, new Class[]{interfaces[0]}, invocationHandler);
}
}
//@RunWith(SpringRunner.class)
//@SpringBootTest
public class VideoApplicationTest {
@Autowired
// private static QNStreamAdapter qnStreamAdapter;
private static QNStreamAdapter qnStreamAdapter = new QNStreamAdapter();
private static UCStreamAdapter ucStreamAdapter = new UCStreamAdapter();
private static XStreamAdapter xStreamAdapter = new XStreamAdapter();
// @Test
public static void main(String[] args) throws Exception {
// 让代理对象的class文件写入到磁盘(必须是标准的 main 方法才行)
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
IVideoAuditService qnProxy = VideoProxy.getProxy(VideoAuditServiceImpl.class, qnStreamAdapter);
VideoStreamAuditInfo qnInfo = qnProxy.getStreamAuditInfo(100);
System.out.println("QN 视频流审核结果:" + qnInfo);
//
IVideoAuditService ucProxy = VideoProxy.getProxy(VideoAuditServiceImpl.class, ucStreamAdapter);
VideoStreamAuditInfo ucInfo = ucProxy.getStreamAuditInfo(200);
System.out.println("UC 视频流审核结果:" + ucInfo);
IVideoAuditService xProxy = VideoProxy.getProxy(VideoAuditServiceImpl.class, xStreamAdapter);
VideoStreamAuditInfo xInfo = xProxy.getStreamAuditInfo(300);
System.out.println("X 视频流审核结果:" + xInfo);
}
}
参考:
https://bugstack.cn/md/develop/design-pattern/2020-05-24-%E9%87%8D%E5%AD%A6Java%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8A%E6%8A%BD%E8%B1%A1%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E3%80%8B.html