Retrofit turns your HTTP API into a Java interface.
public interface GitHubService {
@GET("users/{user}/repos")
Call> listRepos(@Path("user") String user);
}
The Retrofit class generates an implementation of the GitHubService >interface.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);```
Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.
Call> repos = service.listRepos("octocat");
Use annotations to describe the HTTP request:
首先,我们看下
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
这段代码构建了一个Retrofit对象,让我们看看Builder的代码
/**
* Build a new {@link Retrofit}.
*
* Calling {@link #baseUrl} is required before calling {@link #build()}. All other methods
* are optional.
*/
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private HttpUrl baseUrl;
private final List converterFactories = new ArrayList<>();
private final List adapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
从builder注释中可以这段,在调用build()方法之前,必须设置baseurl
童鞋们,从上面的代码有木有发现两个list
private final List converterFactories = new ArrayList<>();
private final List adapterFactories = new ArrayList<>();
辣么我们来看下
/**
* Convert objects to and from their representation in HTTP. Instances are created by {@linkplain
* Factory a factory} which is {@linkplain Retrofit.Builder#addConverterFactory(Factory) installed}
* into the {@link Retrofit} instance.
*/
public interface Converter {
T convert(F value) throws IOException;
/** Creates {@link Converter} instances based on a type and target usage. */
abstract class Factory {
**
* Adapts a {@link Call} with response type {@code R} into the type of {@code T}. Instances are
* created by {@linkplain Factory a factory} which is
* {@linkplain Retrofit.Builder#addCallAdapterFactory(Factory) installed} into the {@link Retrofit}
* instance.
*/
public interface CallAdapter {
/**
* Returns the value type that this adapter uses when converting the HTTP response body to a Java
* object. For example, the response type for {@code Call} is {@code Repo}. This type
* is used to prepare the {@code call} passed to {@code #adapt}.
*
* Note: This is typically not the same type as the {@code returnType} provided to this call
* adapter's factory.
*/
Type responseType();
/**
* Returns an instance of {@code T} which delegates to {@code call}.
*
* For example, given an instance for a hypothetical utility, {@code Async}, this instance would
* return a new {@code Async} which invoked {@code call} when run.
*
*/
T adapt(Call call);
/**
* Creates {@link CallAdapter} instances based on the return type of {@linkplain
* Retrofit#create(Class) the service interface} methods.
*/
abstract class Factory {
哦,CallAdapter是将Call 转换成T(这就是rxjavaAdapter实现的接口)
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
当我们使用Retrofit时,我们先 然后我们看下Retrofit.Builder;
Builder(Platform platform) {
this.platform = platform;
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
}
public Builder() {
this(Platform.get());
}
static final class BufferingResponseBodyConverter
implements Converter {
static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();
@Override public ResponseBody convert(ResponseBody value) throws IOException {
try {
// Buffer the entire body to avoid future I/O.
return Utils.buffer(value);
} finally {
value.close();
}
}
}
//Utils.java
static ResponseBody buffer(final ResponseBody body) throws IOException {
Buffer buffer = new Buffer();
body.source().readAll(buffer);
return ResponseBody.create(body.contentType(), body.contentLength(), buffer);
}
同样的BufferingResponseBodyConverter,convert函数参数是ResponseBody类型,返回也是ResponseBody类型,和BufferingResponseBodyConverter不同的是BufferingResponseBodyConverter将ResponseBody的流buffer下来再构建了一个新的ResponseBody;所以我们可以认为当type是ResponseBody类型的时候,BuiltInConverters对HTTP返回结果没有进行转换处理。 那么我们来看看当type is Void
static final class VoidResponseBodyConverter implements Converter {
static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();
@Override public Void convert(ResponseBody value) throws IOException {
value.close();
return null;
}
}
然后我们看看 new Retrofit.Builder() .baseUrl("https://api.github.com/") .build(); 的build
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
List converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
build的第一行代码
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
class Platform {
private static final Platform PLATFORM = findPlatform();
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
@Nullable Executor defaultCallbackExecutor() {
return null;
}
CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor != null) {
return new ExecutorCallAdapterFactory(callbackExecutor);
}
return DefaultCallAdapterFactory.INSTANCE;
}
boolean isDefaultMethod(Method method) {
return false;
}
@Nullable Object invokeDefaultMethod(Method method, Class> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
throw new UnsupportedOperationException();
}
@IgnoreJRERequirement // Only classloaded and used on Java 8.
static class Java8 extends Platform {
@Override boolean isDefaultMethod(Method method) {
return method.isDefault();
}
@Override Object invokeDefaultMethod(Method method, Class> declaringClass, Object object,
@Nullable Object... args) throws Throwable {
// Because the service interface might not be public, we need to use a MethodHandle lookup
// that ignores the visibility of the declaringClass.
Constructor constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
return constructor.newInstance(declaringClass, -1 /* trusted */)
.unreflectSpecial(method, declaringClass)
.bindTo(object)
.invokeWithArguments(args);
}
}
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
}
Builder(Platform platform) {
this.platform = platform;
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
}
public Builder() {
this(Platform.get());
}
当我们new Buidler时会get一个Android Platform, 我们来看看
static class Android extends Platform {
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor {
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
// Make a defensive copy of the adapters and add the default Call adapter.
List adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter
我们从get方法看起, 当return的类型不是call类型,直接return,
static Type getCallResponseType(Type returnType) {
if (!(returnType instanceof ParameterizedType)) {
throw new IllegalArgumentException(
"Call return type must be parameterized as Call or Call extends Foo>");
}
return getParameterUpperBound(0, (ParameterizedType) returnType);
}
new CallAdapter>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call adapt(Call call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
首先看看 WeakReference
wiki 上 Weak reference 的一个例子:
public class ReferenceTest {
public static void main(String[] args) throws InterruptedException {
WeakReference r = new Wea
有一个线上环境使用的是c3p0数据库,为外部提供接口服务。最近访问压力增大后台tomcat的日志里面频繁出现
com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResou
https://weblogs.java.net/blog/mriem/archive/2013/11/22/jsf-tip-45-create-composite-component-custom-namespace
When you developed a composite component the namespace you would be seeing would
一、复本集为什么要加入Arbiter这个角色 回答这个问题,要从复本集的存活条件和Aribter服务器的特性两方面来说。 什么是Artiber? An arbiter does
not have a copy of data set and
cannot become a primary. Replica sets may have arbiters to add a
# include <stdio.h>
int main(void)
{
int a[5] = {1, 2, 3, 4, 5};
//a 是数组的名字 5是表示数组元素的个数,并且这五个元素分别用a[0], a[1]...a[4]
int i;
for (i=0; i<5; ++i)
printf("%d\n",