Вы можете использовать эту пользовательскую библиотеку (написанную с помощью Promise) для выполнения удаленного вызова.
function $http(apiConfig) {
return new Promise(function (resolve, reject) {
var client = new XMLHttpRequest();
client.open(apiConfig.method, apiConfig.url);
client.send();
client.onload = function () {
if (this.status >= 200 && this.status < 300) {
// Performs the function "resolve" when this.status is equal to 2xx.
// Your logic here.
resolve(this.response);
}
else {
// Performs the function "reject" when this.status is different than 2xx.
reject(this.statusText);
}
};
client.onerror = function () {
reject(this.statusText);
};
});
}
Пример простого использования:
$http({
method: 'get',
url: 'google.com'
}).then(function(response) {
console.log(response);
}, function(error) {
console.log(error)
});
Tricky.
Асинхронное поведение добавляется через проксирование.
Spring предоставляет вам прокси-сервер, который обертывает фактический объект и выполняет фактический вызов в отдельном потоке.
Это выглядит примерно так (за исключением того, что большинство из них выполняется динамически с помощью прокси-серверов CGLIB или JDK и обработчиков Spring)
class ProxyListener extends ActivityMessageListener {
private ActivityMessageListener real;
public ProxyListener(ActivityMessageListener real) {
this.real = real;
}
TaskExecutor executor; // injected
@Override
public void doReceive(Message message) throws Exception {
executor.submit(() -> real.doReceive(message)); // in another thread
}
}
ActivityMessageListener real = new ActivityMessageListener();
ProxyListener proxy = new ProxyListener(real);
Теперь, в весеннем мире, у вас будет ссылка на объект proxy
, а не на ActivityMessageListener
. Это
ActivityMessageListener proxy = applicationContext.getBean(ActivityMessageListener.class);
вернет ссылку на ProxyListener
. Затем через полиморфизм вызов doReceive
перейдет к методу overriden Proxy#doReceive
, который будет вызывать ActivityMessageListener#doReceive
посредством делегирования, и вы получите свое асинхронное поведение.
Однако вы находитесь в половине Весенний мир.
Здесь
public ActivityMessageListener() {
MessageBusUtil.addQueue(MKTDestinationNames.ACTIVITY_REGISTRY, this);
}
ссылка this
на самом деле относится к реальному ActivityMessageListener
, а не к прокси. Поэтому, когда, предположительно, вы отправляете свое сообщение на автобусе здесь
MessageBusUtil.sendMessage(MKTDestinationNames.ACTIVITY_REGISTRY, message);
, вы отправляете его реальному объекту, который не имеет асинхронного поведения прокси.
Полное решение Spring будет состоять в том, чтобы MessabeBus (и / или его очередь) были Spring beans, в которые вы можете вводить полностью обработанные (проксированные, автоувещенные, инициализированные) bean-компоненты.
На самом деле, поскольку прокси-серверы CGLIB - это действительно просто подклассы ваших типов, поэтому ProxyListener
выше действительно добавит себя к шине, так как будет вызываться конструктор super
. Казалось бы, только один MessageListener
может зарегистрировать себя с помощью ключа, например MKTDestinationNames.ACTIVITY_REGISTRY
. Если это не так, вам нужно будет показать больше этого кода для объяснения.
В вашем тесте, если вы делаете
activityMessageListener.doReceive(message);
, вы должны см., что асинхронное поведение, поскольку activityMessageListener
должно содержать ссылку на прокси.