Секреты Java
Открыть в Telegram
Обсуждаем Java, архитектуру, фреймворки и всё, о чем должны говорить разработчики. Владелец: @Alexey_Morl Реклама на бирже: https://telega.in/c/java_secrets
Больше7 991
Подписчики
Нет данных24 часа
Нет данных7 дней
Нет данных30 день
Архив постов
7 991
Начните обучение в магистратуре в Центральном университете уже на 3-м курсе бакалавриата!
Центральный университет — современный вуз, созданный при поддержке ведущих компаний России: Т-Банка, Авито и других.
Учебу реально совместить с последними курсами бакалавриата или действующей работой. Обучение занимает 20 часов в неделю в вечернее время в первый год, а занятия проводят в центре Москвы профессоры из МГУ, МФТИ, РЭШ и практики из индустрии. Обучение в университете построено по принципам ИТ-компаний, со средой, способствующей росту и развитию.
У каждого студента будет:
● личный ментор по траектории обучения;
● доступ к карьерному центру с коучами и консультантами;
● опыт работы в проектах 30+ компаний-партнеров уже во время обучения;
● диплом гособразца.
Участвуйте в онлайн-отборе, чтобы выиграть грант на обучение до 1,2 млн рублей. Больше подробностей про университет и конкурс грантов по ссылке!
erid:2Vtzqwidrq1
Реклама, АНО ВО «Центральный университет», ИНН 774341802
7 991
✅ Язык выражений Spring
Spring Expression Language (SpEL) — это язык выражений, встроенный в Spring Framework, который позволяет вычислять выражения в runtime. С его помощью можно обращаться к свойствам объектов, вызывать методы, работать с массивами, коллекциями и т.д.
SpEL выражения имеют вид
#{выражение}, а если нужно указать ссылку на свойство из файла конфигурации application.yml, то в место # используется знак $.
SpEL часто применяется с аннотацией @Value для внедрения значения свойств.
@Value("${property}")
private String value;
Язык выражений поддерживает:
▫️логические и математические операции
▫️регулярные выражения
▫️доступ к полям, массивам, спискам
▫️вызов методов
Для примера определим класс Address, который будет содержать поле с указанием города.
@Component
public class Address {
public String city = "Moscow";
}
В другом классе используя @Value + SpEL можем получить данные из класса Address:
@Value("#{address.city}")
private String value;
Можем преобразовать значение:
@Value("#{address.city.toUpperCase()}")
private String value;
Проверить на соответствие регулярному выражению:
@Value("#{address.city matches '[a-zA-Z]+'}")
private boolean value;
Так же SpEL поддерживает сокращенный тернарный оператор:
@Value("#{address.city?:'Unknown'}")
private String value;
#{address.city?:'Unknown'} эквивалентно #{address.city != null ? address.city :'Unknown'}
SpEL можно использовать в различных Spring аннотациях, в xml конфигурации, а так же у Spring есть набор классов для работы со SpEL выражениями.
🫡 Секреты Java
#java #spring #spel7 991
Тестовое собеседование на Middle Java-разработчика завтра
7 августа(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
1. Степан Аракелян, ex-Tech Lead в МТС и ментор в ШОРКТАТ, проведет настоящее собеседование на Middle Java-разработчика
2. Степан будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
3. В конце можно будет задать любой вопрос Степану
Что узнаешь на прямом эфире от ШОРТКАТ:
- Чего ждут от кандидатов на Middle позиции в Java-разработке
- Какие вопросы задают на интервью и зачем
- Как подготовиться к собесу, чтобы получить оффер
Это бесплатно?
Бесплатно
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
7 991
✅ TreeSet
TreeSet - это множество уникальных и упорядоченных (в отличии от HashSet) элементов. TreeSet наследуется от AbstractSet и реализует интерфейс NavigableSet. Эта коллекция под капотом имеет TreeMap, которая использует для хранения бинарное красно-черное дерево, из-за чего элементы в этой структуре данных хранятся в отсортированном порядке.
Так как при вставке и поиске значений TreeSet использует сравнение через метод
compare/compateTo, то добавляемые элементы должны реализовывать интерфейс Comparable, либо при создании коллекции TreeSet через конструктор необходимо указать Comparator.
Передавая через конструктор реализацию Comparator можно изменить способ сортировки элементов в коллекции.
Set<Integer> tree = new TreeSet<>(Comparator.reverseOrder());
При указании Comparator нужно быть аккуратным, так как TreeSet гарантирует уникальность элементов, сравнивая их через метод compare/compateTo !
Set<String> tree = new TreeSet<>(Comparator.comparing(String::length));
tree.add("Hello");
tree.add("World");
В данном примере TreeSet сравнивает строки по их длине. Так как "Hello" и "World" имеют одинаковую длину, то в коллекцию будет добавлена только первая строка.
Данную коллекцию имеет смысл использовать если:
▫️нужна автоматическая сортировка уникальных элементов
▫️необходимо быстро находить элементы в определенном диапазоне
🫡 Секреты Java
#java #set7 991
✅ Условия в Spring
При разработке приложений с использование Spring иногда возникает необходимость включать некоторые бины в зависимости от условий.
Например, может быть необходимо включить другую имплементацию сервиса или отключить тесты.
Для этой цели в Spring есть группа аннотаций
@Conditional
▫️@ConditionalOnProperty - проверяет параметр из конфигурационного файла
▫️@ConditionalOnJava - проверяет версию Java
▫️@ConditionalOnResource - проверяет наличие нужного ресурса в classpath
▫️@ConditionalOnExpression - проверяет SpEL выражение
и другие
@Configuration
public class CacheConfiguration {
@Bean
@ConditionalOnProperty(name = "cache.type", havingValue = "redis")
public CacheManager redisCacheManager() {
return new RedisCacheManager();
}
@Bean
@ConditionalOnProperty(name = "cache.type", havingValue = "caffeine")
public CacheManager caffeineCacheManager() {
return new CaffeineCacheManager();
}
}
В данном примере включается нужный бин менеджера кеша в зависимости от значения свойства cache.type из файла application.properties.
cache.type=${CACHE_TYPE:redis}
Используя формат ${SYS_PROPERTY:default_value} в конфигурационном файле Spring возьмет значение переменной среды окружения, если она определена, иначе подставит дефолтное значение.
В данном случае, если не определена переменная среды окружения CACHE_TYPE, то для свойства cache.type будет использоваться значение redis. И на основе этого свойства во время сканирования бинов Spring проигнорирует бин caffeineCacheManager и загрузит только redisCacheManager.
🫡 Секреты Java
#java #spring #conditional7 991
Представьте себе мир, где вы создаёте игры и приложения, которые покоряют сердца миллионов пользователей. Ваши идеи оживают на экранах смартфонов и компьютеров, а вы наслаждаетесь свободой и гибкостью фриланса.
Java — один из самых популярных языков программирования, который используют разработчики для создания различных приложений. Если вы давно мечтаете попробовать себя в этой сфере, скорее записывайтесь на мини-курс по Java-разработке: https://epic.st/oGWvK1?erid=2VtzqwmHFWj
🎉 Подарок за регистрацию — гайд по профессии Java-разработчика.
Формат мини-курса отлично подойдёт для обучения из любой точки мира: смотрите видео в удобное время и закрепляйте навыки на практике. Больше не надо искать свободное время, чтобы прийти на вечерний вебинар, или ждать записи в случае пропуска.
Хватит мечтать, пора реализовывать!
Реклама. ЧОУ ДПО «Образовательные технологии «Скилбокс (Коробка навыков)», ИНН: 9704088880
7 991
✅ Разработка REST клиентов
OpenFeign - это библиотека для написания REST клиента, являющаяся детищем Netflix, которая позволяет в декларативном формате настраивать подключение к внешним сервисам. Одним из основных преимуществ OpenFeign являются аннотированные интерфейсы, избавляющие вас от написания шаблонного кода.
Spring Cloud предоставляет простую интеграцию OpenFeign с сервисами Spring:
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
Помимо этого Spring Cloud Open Feign легко настроить на работу с другими облачными службами обеспечивающими балансировку нагрузки, отказоустойчивость и обнаружения сервисов.
Для определения REST клиента достаточно создать интерфейс помеченный аннотацией @FeinClient.
@FeignClient(name = "testApi", url = "https://testapi.jasonwatmore.com")
public interface TestApiClient {
@GetMapping("/products")
List<Product> getProducts();
@GetMapping("/products/{id}")
Product getProductById(@PathVariable("id") Long id);
}
В данном примере настроен клиент для получения тестовых данных с сервиса jasonwatmore.
Аннотация @FeignClient указывает на то, что на основе этого интерфейса Spring создаст реализацию REST клиента. Через аргумент name указывается имя для этого клиента, а аргумент url служит для определения базового URL API.
Методы этого интерфейса служат для определения конкретных запросов к API, которыми мы будем пользоваться. Эти методы помечаются знакомыми вам аннотациями из RestController. С помощью них вы можете указывать тип запроса, принимаемые параметры и возвращаемый результат.
Так же необходимо указать аннотацию @EnableFeignClient над (классом с @Configuration или @SpringBootApplication) , с помощью которой Spring поймет, что ему нужно просканировать директорию для поиска интерфейсов, являющихся REST клиентами.
Чтобы использовать этот клиент, его достаточно заинжектить в ваш сервисный класс.
@Service
public class ProductService {
@Autowired
private TestApiClient testApiClient;
...
И это все!
Простота использования аннотированных интерфейсов, поддержка работы с другими облачными службами и полная интеграция с Spring Boot делают OpenFeign отличным инструментом для разработки современных микросервисных архитектур.
🫡 Секреты Java
#java #openfeign7 991
Привет! Рекомендую подписаться на канал Java: fill the gaps, полезно для разработчиков любого уровня🔥
Для продолжающих:
🔹 Как реализованы лямбда выражения внутри JVM
🔹 Библиотеки работы с данными: от JDBC до Spring Data
🔹 3 способа подружить Postgres и Kafka
Для начинающих:
🔸 5 ошибок при использовании Optional
🔸 Fluent API: что такое и зачем нужен
🔸 Как освоить многопоточку
Подписывайся👉 Java: fill the gaps
7 991
✅ Классы с поддержкой атомарных операций
Если в вашем коде нужна переменная, к которой будут обращаться разные потоки не только для чтения, но и для записи, можно использовать
volatile + synchronized. Но это влечет за собой потери в производительности.
Для решения этой проблемы в Java есть пакет java.concurrent.atomic, который содержит классы для работы с атомарными операциями.
Атомарная операция - это операция, которая может быть безопасно выполнена в многопоточной среде.
Классы из пакета java.concurrent.atomic используют низкоуровневые операции, такие как CAS (compare-and-swap). Подобные инструкции работают быстрее, чем синхронизация через блокировки потоков.
Вот пример использования класса AtomicInteger:
public class Counter {
private final AtomicInteger counter = new AtomicInteger(0);
int getValue() {
return counter.get();
}
void increment() {
counter.incrementAndGet();
}
}
В данном коде определяется переменная counter типа AtomicInteger, через метод getValue() можно получить текущее значение счетчика, а через increment() - увеличить его значение. В этом примере мы можем быть уверены, что в многопоточной среде этот класс будет иметь предсказуемое поведение!
Класс AtomicInteger содержит множество методов для выполнения атомарных операций:
▫️incrementAndGet() - увеличивает на единицу значение и возвращает значение
▫️getAndIncrement() - возвращает значение и после увеличивает значение на единицу
▫️ decrementAndGet() и getAndDecrement() - работают аналогично increment методам, но уменьшают значение
▫️ set(int value) - присваивает новое значение
А так же множество других методов.
Помимо AtomicInteger, существуют подобные классы для работы с Boolean, Long, массивами и ссылками на объекты.
Использование этих классов позволяет избавить от лишних блоков синхронизации потоков, которые могут вызвать deadlock. Несмотря на высокую производительность этих классов, не стоит их использовать в однопоточных программах, так как накладные расходы на выполнение атомарных операций увеличивают время выполнения кода.
🫡 Секреты Java
#java #atomic #multithreading7 991
✅ Паттерн Observer или Наблюдатель
Observer — это поведенческий паттерн, который определяет зависимость "один ко многим" между объектами таким образом, что при изменении состояния одного объекта все зависящие от него объекты оповещаются и обновляются автоматически.
Для реализации этого паттерна определим два интерфейса.
Первый для наблюдаемого объекта:
public interface Observable {
void registerObserver(Observer observer);
void unregisterObserver(Observer observer);
void notifyObservers();
}
Второй для наблюдателя:
public interface Observer {
void update(String news);
}
Для примера создадим новостной блог, который будет реализовывать интерфейс Observable:
public class NewsBlog implements Observable {
private String news;
private Set<Observer> observers = new HashSet<>();
public void setNews(String news) {
this.news = news;
notifyObservers();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void unregisterObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers)
observer.update(news);
}
}
Этот класс хранит список подписчиков, умеет их регистрировать и удалять, а также, при публикации новости, он оповещает подписчиков.
Создадим простую реализацию подписчика, который будет выводить полученное сообщение в консоль:
public class Subscriber implements Observer{
@Override
public void update(String news) {
System.out.println(news);
}
}
Напишем тестовый пример, чтобы убедится в правильности работы:
public static void main(String[] args) {
NewsBlog newsBlog = new NewsBlog();
newsBlog.registerObserver(new Subscriber());
newsBlog.registerObserver(new Subscriber());
newsBlog.setNews("Hello!");
}
При запуске этого кода каждый Subscriber должен вывести в консоль полученное сообщение.
Паттерн Наблюдатель полезен для построения систем, которые реагирую на изменение в компонентах.
Этот паттерн позволяет:
▫️добавлять новых наблюдателей без изменения существующего кода;
▫️реализовывать независимых друг от друга наблюдателей, каждый из которых может выполнять свою бизне-логику.
🫡 Секреты Java
#java #pattern #observer