CallKeLinServiceProxyConfiguration.java
3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.zteits.charge.config;
import com.zteits.charge.service.spi.CallBusinessInfoSpi;
import com.zteits.charge.service.spi.CallStationInfoSpi;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 调用科林接口代理类,实现加密和签名
*
* <p>⚠️ 这里**故意删掉了**老代码上的 {@code @ComponentScan}(无参数版),它不是「少了个配置」,
* 而是合并单 Jar 时的一个坑,详见 AGENTS.md 坑 14:
*
* <p>无参数 {@code @ComponentScan} 扫的是**本类所在包** {@code com.zteits.charge.config}。
* 合并单 Jar 后,这个包名同时被**封闭 Jar**({@code zteits-parking-charge-spring-boot-starter},
* 源码不可改)占用,于是它会把那个 Jar 里的 {@code ChargeConfig} 一起扫进来注册成
* {@code @Configuration};而 {@code ChargeConfig} 自己又带
* {@code @ComponentScan("com.zteits.charge")},会再触发一整轮**不受启动类过滤器约束**的扫描,
* 最终抛出 {@code BeanDefinitionOverrideException}({@code @Bean("chargeService")} 撞
* {@code @Component ChargeService})。
*
* <p>删掉它是**零损失**的:启动类 {@code ParkingServerApplication} 的
* {@code @ComponentScan} 已经包含 {@code com.zteits.charge},本包下的
* {@code KeLinOkHttpHelper} 等组件本来就会被扫到(实测启动日志里它们由启动类那一轮扫描注册,
* 后一轮重复扫描对已注册的同源 Bean 是空操作)。老工程 7 个 JVM 里
* {@code ChargeApplication} 同样扫 {@code com.zteits.charge},所以这一行在老工程里也是冗余的。
*/
@Slf4j
@Configuration
@RequiredArgsConstructor
public class CallKeLinServiceProxyConfiguration {
private Lock lock = new ReentrantLock();
final KeLinOkHttpHelper keLinOkHttpHelper;
@Bean
@ConditionalOnMissingBean
public CallStationInfoSpi getStationService(){
return (CallStationInfoSpi) Proxy.newProxyInstance(
CallKeLinServiceProxyConfiguration.class.getClassLoader(),
new Class[] { CallStationInfoSpi.class },
new ChargingInvocationHandler()
);
}
@Bean
@ConditionalOnMissingBean
CallBusinessInfoSpi getBusinessService(){
return (CallBusinessInfoSpi) Proxy.newProxyInstance(
CallKeLinServiceProxyConfiguration.class.getClassLoader(),
new Class[] { CallBusinessInfoSpi.class },
new ChargingInvocationHandler()
);
}
@RequiredArgsConstructor
public class ChargingInvocationHandler implements InvocationHandler{
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ApiName apiName = method.getAnnotation(ApiName.class);
return keLinOkHttpHelper.post(apiName.value(),(String)args[0], args[1], method.getReturnType());
}
}
}