ismart-yuxi / retrofit-spring-boot-demo

retrofit-spring-boot-demo
26 stars 21 forks source link

替换默认的BaseOkHttpClient 为啥没有执行呢 #2

Open demidroid opened 1 year ago

potoo0 commented 5 months ago

因为这个库的 okhttpclient 不是直接从容器中拿 bean,源码 RetrofitFactoryBean#createOkHttpClient

不修改源码情况下可以在获取 bean 前修改注解的值,来修改 okhttpclient,完整实例:

@Component
public class Demo {
    @Component
    public static class DemoBeanPostProcessor implements BeanPostProcessor {
        @SuppressWarnings({"unchecked", "rawtypes"})
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            // log.info(">>>>> bean: {}, beanName: {}", bean, beanName);
            if (bean instanceof RetrofitFactoryBean) {
                RetrofitFactoryBean retrofitFactoryBean = (RetrofitFactoryBean) bean;
                Class objectType = retrofitFactoryBean.getObjectType();
                log.info(">>>>> retrofit client: {}", objectType);
                Annotation annotation = objectType.getAnnotation(RetrofitClient.class);
                InvocationHandler handler = Proxy.getInvocationHandler(annotation);
                try {
                    Field memberValuesField = handler.getClass().getDeclaredField("memberValues");
                    memberValuesField.setAccessible(true);
                    Map memberValues = (Map) memberValuesField.get(handler);
                    memberValues.put("sourceOkHttpClient", "noSSL");
                } catch (Exception e) {
                    log.error(e.getMessage());
                }
            }
            return bean;
        }
    }

    @Component
    public static class CustomOkHttpClientRegistrar implements SourceOkHttpClientRegistrar {
        @Override
        public void register(SourceOkHttpClientRegistry registry) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .addInterceptor(chain -> {
                        log.info(">>> request: url={}", chain.request().url());
                        return chain.proceed(chain.request());
                    })
                    .connectTimeout(Duration.ofSeconds(1))
                    .writeTimeout(Duration.ofSeconds(5))
                    .readTimeout(Duration.ofSeconds(5));
            skipCertificate(builder);
            registry.register("noSSL", builder.build());
        }

        @SneakyThrows
        public static void skipCertificate(OkHttpClient.Builder builder) {
            // Create a trust manager that does not validate certificate chains
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };

            // Install the all-trusting trust manager
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // Create a ssl socket factory with our all-trusting manager
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

            builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
            builder.hostnameVerifier((hostname, session) -> true);
        }
    }
}