RestTemplate должен быть статическим глобально объявленным?
я использую Java Callable Future в своем коде. Ниже приведен мой основной код, который использует future и callables -
public class TimeoutThread {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(5);
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
ниже Task
класс, который реализует вызываемый интерфейс, и мне нужно создать URL-адрес в зависимости от имени хоста, который у нас есть, а затем позвонить на серверы, используя RestTemplate
. Если есть какое-либо исключение в первом имени хоста, то я создам URL для другого имени хоста, и я попытаюсь сделать вызов.
class Task implements Callable<String> {
private static RestTemplate restTemplate = new RestTemplate();
@Override
public String call() throws Exception {
//.. some code
for(String hostname : hostnames) {
if(hostname == null) {
continue;
}
try {
String url = generateURL(hostname);
response = restTemplate.getForObject(url, String.class);
// make a response and then break
break;
} catch (Exception ex) {
ex.printStackTrace(); // use logger
}
}
}
}
поэтому мой вопрос должен я объявить RestTemplate
как статическая глобальная переменная? Или он не должен быть статичным в этом случае?
3 ответов
это не имеет значения, в любом случае, static
или экземпляра.
RestTemplate
методы для создания HTTP-запросов являются потокобезопасными, поэтому есть ли у вас RestTemplate
экземпляр на Task
экземпляр или общий экземпляр для всех Task
экземпляров (за исключением мусора).
лично я бы создать RestTemplate
за пределами Task
класса и передать его в качестве аргумента Task
конструктор. (По возможности используйте инверсию управления.)
С точки зрения параллелизма, это не имеет значения. RestTemplate
является потокобезопасным, поэтому один экземпляр или несколько экземпляров для нормального функционирования программы.
но вы можете рассмотреть AsyncRestTemplate
вместо этого, как показано здесь.
кроме того, как упоминают другие, вы должны рассмотреть подход МОК, чтобы отделить создание вашего клиента REST от его использования. этой статья Мартина Фаулера-это плодотворное обсуждение тема.
в моем конкретном случае я нашел некоторые причины, по которым можно захотеть иметь более одного экземпляра RestTemplate
.
RestTemplate-это способ вызвать удаленную конечную точку, но интеграция HTTP выглядит обманчиво простой, и когда вы начинаете находить специальные сценарии, которые не применяются ко всем вызовам API, когда вы понимаете, что вам нужен способ определить некоторые параметры в каждом конкретном случае.
примерами таких сценариев являются следующий:
- у нас разные команды в компании,и по ошибке мы не договорились о формате времени, который мы хотели использовать в наших моделях. Теперь разные API из разных команд используют разные форматы времени, которые заставили нас определить разные настройки JSON mapper для этих случаев. Это также может произойти, если вам нужно вызвать сторонние службы.
- не все API, которые мы называем, имеют одинаковые соглашения об уровне обслуживания или ведут себя одинаково в течение всего года. В высоком сезон некоторые API могут поддерживать больше трафика и т. д. Это означает, что параметры тайм-аута соединения могут отличаться для разных API, а иногда даже в зависимости от требований. Таким образом, такие параметры, как тайм-аут соединения, тайм-аут чтения и тайм-аут записи, могут быть настроены по-разному в зависимости от вызываемой службы.
- возможно установка автомата защити цепи, как то из Hytrix, может быть установлена в обслуживание, и поэтому иметь экземпляр RestTemplate в обслуживание позволяет дополнительная возможность настройки параметров в каждом конкретном случае.