Java for Beginner
673 subscribers
541 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
400к+: "О, я Вас кажется знаю, Вы же у нас работаете,да?" 🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Зачем нужно AOP?

Основная задача AOP — изолировать сквозную функциональность, которую сложно выразить через объектно-ориентированное программирование. AOP упрощает код, устраняя необходимость дублирования.

Примеры сквозной функциональности

Логирование:
Логировать действия пользователя, запросы или ошибки.

@Before("execution(* com.example.controller.*.*(..))")
public void logRequest() {
System.out.println("Handling request...");
}


Управление транзакциями:
Начало и завершение транзакции при выполнении метода.

@Around("@annotation(org.springframework.transaction.annotation.Transactional)")
public Object manageTransaction(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Transaction started");
Object result = joinPoint.proceed();
System.out.println("Transaction committed");
return result;
}


Авторизация:
Проверка, имеет ли пользователь доступ к определённому ресурсу.

@Before("execution(* com.example.service.*.*(..))")
public void checkAuthorization() {
if (!isAuthorized()) {
throw new SecurityException("User is not authorized");
}
}


Отслеживание производительности:
Логирование времени выполнения метода.

@Around("execution(* com.example.service.*.*(..))")
public Object logPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long elapsedTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + elapsedTime + "ms");
return result;
}


Основные преимущества использования AOP

Модульность:
Сквозная функциональность сосредоточена в аспектах, что упрощает сопровождение кода.

Читаемость:
Устранение дублирования. Бизнес-логику можно сосредоточить в одном месте.

Гибкость:
Возможность легко изменять аспекты без изменения основного кода.

Повышение тестируемости:
Сквозную функциональность можно тестировать отдельно.

Практический пример: Логирование запросов

Аспект для логирования:
@Aspect
@Component
public class RequestLoggingAspect {

@Before("execution(* com.example.controller.*.*(..))")
public void logRequest(JoinPoint joinPoint) {
System.out.println("Request to: " + joinPoint.getSignature());
}
}


Контроллер:
@RestController
public class UserController {

@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id) {
return "User with ID: " + id;
}
}
Результат: Каждый запрос к контроллеру будет логироваться через аспект.


Когда AOP использовать не следует?

Сложная логика аспекта:
Если аспект содержит значительную часть логики, его тестирование и сопровождение могут усложниться.

Чрезмерное использование:
Злоупотребление AOP может сделать проект сложным для понимания из-за "невидимых" операций.

#Java #Training #Spring #AOP
Понятия Joinpoint, Pointcut, Advice

В AOP (аспектно-ориентированном программировании) три ключевых концепции — Joinpoint, Pointcut и Advice — определяют, как и где выполняется логика аспектов. Эти понятия позволяют чётко определить, где вставлять дополнительную функциональность, и упростить реализацию сквозных задач.

Joinpoint


Joinpoint — это конкретная точка в выполнении программы, где аспект может быть применён.

Примеры:
Вызов метода.
Выполнение метода.
Обработка исключений.


Примеры Joinpoint в Spring AOP

Spring поддерживает только Joinpoint, связанные с методами:
Вызов метода (method execution).
Перехват аргументов метода.
Обработка результата или исключения.


Пример:
@Before("execution(* com.example.service.UserService.*(..))")
public void logMethodCall(JoinPoint joinPoint) {
System.out.println("Method called: " + joinPoint.getSignature());
System.out.println("Arguments: " + Arrays.toString(joinPoint.getArgs()));
}


Основные методы Joinpoint

getSignature(): возвращает информацию о вызываемом методе.
getArgs(): возвращает массив аргументов метода.
getTarget(): объект, на котором вызван метод.
getThis(): прокси-объект, созданный Spring AOP.


Пример использования:
@After("execution(* com.example.service.UserService.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("Executed method: " + joinPoint.getSignature().getName());
}


Pointcut

Pointcut — это выражение, определяющее набор Joinpoint, к которым будет применяться аспект.
Pointcut помогает сосредоточить внимание только на нужных местах кода.


В Spring используются SpEL (Spring Expression Language) для создания срезов:

По классу и методам:
execution(* com.example.service.UserService.*(..))


По пакетам:
execution(* com.example..*(..)) // Все методы во всех пакетах


По аннотациям:
@annotation(org.springframework.transaction.annotation.Transactional)


Пример:
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayerMethods() {}
Теперь serviceLayerMethods() можно использовать как ссылку на срез.


Advice

Advice — это дополнительная логика, которая выполняется в определённой точке выполнения программы (Joinpoint).
Advice описывает, что нужно выполнить.

Типы Advice в Spring

@Before: выполняется перед вызовом метода.
@Before("execution(* com.example.service.UserService.*(..))")
public void logBefore() {
System.out.println("Method is about to be called");
}


@After: выполняется после завершения метода (независимо от результата).
@After("execution(* com.example.service.UserService.*(..))")
public void logAfter() {
System.out.println("Method has been executed");
}


@AfterReturning: выполняется, если метод завершился успешно.
@AfterReturning(pointcut = "execution(* com.example.service.UserService.*(..))", returning = "result")
public void logAfterReturning(Object result) {
System.out.println("Method returned value: " + result);
}


@AfterThrowing: выполняется при выбросе исключения.
@AfterThrowing(pointcut = "execution(* com.example.service.UserService.*(..))", throwing = "exception")
public void logAfterThrowing(Exception exception) {
System.out.println("Exception thrown: " + exception.getMessage());
}


@Around: оборачивает выполнение метода, позволяет контролировать его выполнение.
@Around("execution(* com.example.service.UserService.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method execution");
Object result = joinPoint.proceed();
System.out.println("After method execution");
return result;
}


#Java #Training #Spring #AOP #Joinpoint #Pointcut #Advice
Что выведет код?

import java.util.Locale;

public class Task031224_1 {
public static void main(String[] args) {
String template = "Value: %.2f, Hex: %04x, Bool: %b";

String result1 = String.format(template, 12.34567, 255, null);
String result2 = String.format(Locale.US, template, 0.1, 16, true);

System.out.println(result1);
System.out.println(result2);
}
}


#Tasks
Неожиданно, о требованиях HR 😱😂

https://t.me/Java_for_beginner_dev

#Mems
Создание простого аспекта

Теперь разберёмся, как создать и настроить простой аспект в Spring.

Шаг 1: Добавьте зависимость

Добавьте зависимость Spring AOP в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>


Шаг 2: Включите поддержку AOP

Добавьте аннотацию @EnableAspectJAutoProxy в конфигурационный класс:
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {}


Шаг 3: Реализация аспекта

Создайте аспектный класс:
@Aspect
@Component
public class LoggingAspect {

@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceMethods() {}

@Before("serviceMethods()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}

@AfterReturning(pointcut = "serviceMethods()", returning = "result")
public void logAfterReturning(Object result) {
System.out.println("Method returned: " + result);
}

@AfterThrowing(pointcut = "serviceMethods()", throwing = "exception")
public void logAfterThrowing(Exception exception) {
System.out.println("Exception: " + exception.getMessage());
}
}


Создайте бизнес-логику:
@Service
public class UserService {
public String getUserById(Long id) {
System.out.println("Fetching user...");
if (id == null) {
throw new IllegalArgumentException("ID cannot be null");
}
return "User" + id;
}
}


Контроллер для проверки:
@RestController
public class UserController {
@Autowired
private UserService userService;

@GetMapping("/users/{id}")
public String getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
}


Результат работы аспекта


При вызове метода getUserById(1):
- @Before: "Before method: getUserById".
- Выполняется логика метода.
- @AfterReturning: "Method returned: User1".

При вызове метода с ошибкой getUserById(null):
- @Before: "Before method: getUserById".
- Метод выбрасывает исключение.
- @AfterThrowing: "Exception: ID cannot be null".

Советы по работе с AOP

Используйте AOP для сквозных задач, таких как:
Логирование.
Транзакции.
Безопасность.


Избегайте чрезмерного использования AOP, чтобы не усложнять отладку.
Структурируйте Pointcut выражения, чтобы аспекты легко переиспользовались.
Тестируйте аспекты отдельно от основной бизнес-логики.

#Java #Training #Spring #AOP #CreateAOP
Аннотации @Before, @After, @Around

Spring AOP предоставляет различные типы советов (Advice), которые позволяют внедрять дополнительную логику в определённые точки выполнения программы.

Аннотация @Before

Аннотация @Before используется для выполнения кода перед вызовом метода.
Срабатывает до метода-цели, вне зависимости от его результата.
Используется для логирования, проверки входных данных, проверки прав доступа и т.д.


@Before("pointcut_expression")
public void adviceMethod(JoinPoint joinPoint) {
// Логика совета
}


Пример использования:
@Aspect
@Component
public class LoggingAspect {

@Before("execution(* com.example.service.UserService.*(..))")
public void logBeforeMethod(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}


Нюансы:
Не контролирует выполнение метода: метод-цель будет вызван независимо от совета.
Не может перехватывать результат или исключение.


Аннотация @After

Аннотация @After используется для выполнения кода после завершения метода, независимо от того, успешно он завершился или выбросил исключение.
Полезна для освобождения ресурсов, записи логов.

@After("pointcut_expression")
public void adviceMethod(JoinPoint joinPoint) {
// Логика совета
}


Пример использования:
@Aspect
@Component
public class CleanupAspect {

@After("execution(* com.example.service.UserService.*(..))")
public void cleanupAfterMethod(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}
}


Нюансы:
Всегда срабатывает после метода, даже если метод выбросил исключение.
Используется для логирования и операций, которые должны быть выполнены в любом случае.


Аннотация @Around

Аннотация @Around оборачивает вызов метода-цели и позволяет полностью контролировать его выполнение.
Может изменять параметры метода и результат.
Позволяет управлять выполнением метода, включая его пропуск или повторное выполнение.
Используется для измерения времени выполнения, транзакционного управления и других сложных сценариев.


@Around("pointcut_expression")
public Object adviceMethod(ProceedingJoinPoint joinPoint) throws Throwable {
// Логика до метода
Object result = joinPoint.proceed(); // Выполнение метода-цели
// Логика после метода
return result;
}


Пример использования:
@Aspect
@Component
public class PerformanceAspect {

@Around("execution(* com.example.service.UserService.*(..))")
public Object measureExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();

Object result = joinPoint.proceed(); // Выполняем метод

long executionTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");

return result;
}
}


Нюансы:
Требует вызова proceed() для выполнения метода-цели.
Может модифицировать результат или перехватывать исключения.
Самая мощная из всех аннотаций, но требует осторожного использования.


#Java #Training #Spring #AOP #Before #After #Around
Что выведет код?

public class Task041224_1 {
public static void main(String[] args) {
boolean a = true;
boolean b = false;
boolean c = true;

boolean result1 = a && (b || c) && !b;
boolean result2 = (a ^ b) || (c && b);
boolean result3 = !(a && c) || (b && !c);

System.out.println(result1);
System.out.println(result2);
System.out.println(result3);
}
}


#Tasks
А ведь раньше логику в школах преподавали...🧐

https://t.me/Java_for_beginner_dev

#Mems
Примеры аспектов

1. Аспект логирования

Этот аспект логирует вызовы методов до и после их выполнения.
@Aspect
@Component
public class LoggingAspect {

@Before("execution(* com.example.service.UserService.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}

@After("execution(* com.example.service.UserService.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}
}


2. Аспект измерения времени выполнения

Измеряет время, которое метод тратит на выполнение.
@Aspect
@Component
public class PerformanceAspect {

@Around("execution(* com.example.service.UserService.*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();

Object proceed = joinPoint.proceed(); // Выполняем метод

long executionTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");

return proceed;
}
}


3. Аспект обработки исключений

Перехватывает и обрабатывает исключения, выбрасываемые методами.

@Aspect
@Component
public class ExceptionHandlingAspect {

@AfterThrowing(pointcut = "execution(* com.example.service.UserService.*(..))", throwing = "exception")
public void logException(JoinPoint joinPoint, Throwable exception) {
System.out.println("Exception in method: " + joinPoint.getSignature().getName());
System.out.println("Exception message: " + exception.getMessage());
}
}


4. Аспект для проверки авторизации

Проверяет, имеет ли пользователь доступ к выполнению метода.
@Aspect
@Component
public class SecurityAspect {

@Before("execution(* com.example.service.SensitiveService.*(..))")
public void checkAccess(JoinPoint joinPoint) {
System.out.println("Checking access before method: " + joinPoint.getSignature().getName());
// Проверка прав доступа
if (!isUserAuthorized()) {
throw new SecurityException("User not authorized");
}
}

private boolean isUserAuthorized() {
// Логика авторизации
return true; // Например, возвращаем всегда true
}
}


5. Аспект кеширования

Кеширует результат выполнения метода.
@Aspect
@Component
public class CachingAspect {

private final Map<String, Object> cache = new HashMap<>();

@Around("execution(* com.example.service.CacheableService.*(..))")
public Object cacheMethod(ProceedingJoinPoint joinPoint) throws Throwable {
String key = joinPoint.getSignature().toString() + Arrays.toString(joinPoint.getArgs());

if (cache.containsKey(key)) {
System.out.println("Returning cached result for " + key);
return cache.get(key);
}

Object result = joinPoint.proceed(); // Выполнение метода
cache.put(key, result);
System.out.println("Caching result for " + key);

return result;
}
}


#Java #Training #Spring #AOP
Что выведет код?

Задача по основам AOP в Spring, понятиям Joinpoint, Pointcut, Advice, аннотациям @Before, @After, @Around. Сложность легкая.

Подробный разбор через 30 минут!🫡

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@SpringBootApplication
@EnableAspectJAutoProxy
public class Task041224_2 {
public static void main(String[] args) {
SpringApplication.run(Task041224_2.class, args);
}

@Bean
public CommandLineRunner demo(Service0412 service) {
return args -> {
service.performTask();
};
}
}

@Component
class Service0412 {
public void performTask() {
System.out.println("Executing performTask...");
}
}

@Aspect
@Component
class LoggingAspect0412 {

@Before("execution(* Service0412.performTask(..))")
public void logBefore() {
System.out.println("Before advice");
}

@After("execution(* Service0412.performTask(..))")
public void logAfter() {
System.out.println("After advice");
}

@Around("execution(* Service0412.performTask(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Around: Before");
Object result = joinPoint.proceed();
System.out.println("Around: After");
return result;
}
}


#TasksSpring
Подробный разбор решения задачи Task041224_2

1. Контекст задачи

Задача демонстрирует основы аспектно-ориентированного программирования (AOP) в Spring. Она показывает, как использовать аннотации AOP (@Before, @After, @Around) для внедрения дополнительного поведения в методы без изменения их исходного кода. Основное внимание уделяется порядку выполнения советов (Advice) и их взаимодействию.

2. Ключевые элементы кода

Аннотация @SpringBootApplication:
Указывает, что класс Main041224_2 является главным классом Spring Boot приложения. Она включает в себя @Configuration, @EnableAutoConfiguration, и @ComponentScan, что автоматически настраивает компоненты Spring, включая поддержку AOP.

Аннотация @EnableAspectJAutoProxy:
Включает поддержку прокси AspectJ, что необходимо для применения аспектов.

Класс Service0412:
Содержит метод performTask(), который выводит сообщение "Executing performTask...". Этот метод становится целью для аспектов.

Класс LoggingAspect0412:
Определен как аспект с помощью аннотации @Aspect.

Он содержит три совета:

@Before:
Метод logBefore() выполняется перед вызовом performTask() и выводит "Before advice".

@After:
Метод logAfter() выполняется после завершения performTask() и выводит "After advice".

@Around:
Метод logAround() оборачивает выполнение performTask():

Выводит "Around: Before" перед вызовом целевого метода.
Выполняет целевой метод с помощью joinPoint.proceed().
Выводит "Around: After" после выполнения метода.


3. Сценарий работы программы

Запуск приложения:
Программа запускается с помощью SpringApplication.run(Main041224_2.class, args);. Контекст Spring создает прокси для Service0412, обеспечивая применение аспектов.

Вызов performTask():
Метод вызывается из CommandLineRunner, что приводит к активации всех аспектов.

Последовательность выполнения:

@Around (первый вызов) — выводит "Around: Before".
@Before — выводит "Before advice".
Выполняется performTask(), выводя "Executing performTask...".
@After — выводит "After advice".
@Around (второй вызов) — выводит "Around: After".

4. Ключевые моменты и выводы

Порядок выполнения советов:
@Around оборачивает выполнение метода, выводя сообщения до и после вызова.
@Before выполняется после первой части @Around, но перед вызовом целевого метода.
@After выполняется после выполнения целевого метода, но до завершения второй части @Around.

Взаимодействие аспектов:
Аспекты работают вместе, добавляя дополнительное поведение. Это позволяет гибко управлять процессом выполнения методов.

Использование прокси:
Аспекты применяются к методам через прокси, что позволяет Spring перехватывать вызовы методов и применять советы.

#Solution_TasksSpring
Pointcut Expressions

Pointcut Expressions — это важный элемент AOP, позволяющий указать, где именно в коде должен срабатывать аспект. С их помощью можно точно определить, какие методы или классы будут подвержены сквозной функциональности.

1. Что такое Pointcut Expressions?

Pointcut — это выражение, определяющее набор точек соединения (Joinpoints), к которым будет применяться аспект. В Spring Pointcut Expressions основываются на синтаксисе AspectJ, что позволяет гибко описывать нужные методы или классы.

2. Основные типы Pointcut Expressions

execution:
Самый часто используемый тип, который указывает выполнение метода.
execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws-pattern?)


Все методы в классе UserService:
execution(* com.example.service.UserService.*(..))


Методы, возвращающие void:
execution(void com.example.service.*.*(..))


Методы с определённым набором параметров:

execution(* com.example.service.UserService.findBy*(String, int))


within:
Указывает на методы, принадлежащие определённому классу или пакету.
within(com.example.service.UserService)


@annotation:
Указывает на методы, которые помечены определённой аннотацией.
@annotation(org.springframework.transaction.annotation.Transactional)


args:
Указывает на методы, принимающие параметры определённого типа.
args(java.lang.String, int)


this / target:
this: срабатывает на прокси-объекты.
target: срабатывает на исходные объекты.

this(com.example.service.UserService)
target(com.example.service.UserService)


3. Комбинирование Pointcut Expressions

Pointcut выражения можно комбинировать с логическими операторами:
&& — И.
|| — ИЛИ.
! — НЕ.


Пример:
@Pointcut("execution(* com.example.service.*.*(..)) && @annotation(org.springframework.transaction.annotation.Transactional)")
public void transactionalMethods() {}


4. Использование Pointcut в аспектах

Определение Pointcut:
@Aspect
@Component
public class LoggingAspect {

@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayerMethods() {}

@Before("serviceLayerMethods()")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}


Применение к методам с аннотацией:
@Before("@annotation(com.example.annotations.Loggable)")
public void logForAnnotatedMethods(JoinPoint joinPoint) {
System.out.println("Logging for annotated method: " + joinPoint.getSignature().getName());
}


#Java #Training #Spring #AOP #Pointcut_Expressions
Что выведет код?

import java.math.BigDecimal;

public class Task051224_1 {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = new BigDecimal("0.3");

BigDecimal sum = a.add(b);
boolean equals1 = sum.equals(c);
boolean equals2 = sum.compareTo(c) == 0;

System.out.println(sum);
System.out.println(equals1);
System.out.println(equals2);
}
}


#Tasks
Гуглишь заявление на увольнение...🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Настройка AOP через XML и аннотации

Spring AOP предоставляет два способа конфигурации: через XML и с помощью аннотаций.

1. Настройка AOP через XML

Ранее в Spring было популярно настраивать AOP через XML-конфигурацию.


Шаги настройки

Добавьте зависимость AOP в pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>


Создайте аспект:
public class LoggingAspect {
public void logBefore() {
System.out.println("Logging before method execution...");
}
}


Определите Pointcut и Advice в XML:
<aop:config>
<aop:aspect id="loggingAspect" ref="loggingAspectBean">
<aop:pointcut id="serviceMethods" expression="execution(* com.example.service.*.*(..))" />
<aop:before method="logBefore" pointcut-ref="serviceMethods" />
</aop:aspect>
</aop:config>


Объявите аспект в applicationContext.xml:
<bean id="loggingAspectBean" class="com.example.aspect.LoggingAspect" />


2. Настройка AOP с помощью аннотаций

Настройка через аннотации является более современным и удобным подходом.

Шаги настройки

Добавьте зависимость:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>


Включите поддержку AOP в приложении:
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {}


Создайте аспект:
@Aspect
@Component
public class LoggingAspect {

@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}

@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("After method: " + joinPoint.getSignature().getName());
}

@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Around - Before method: " + joinPoint.getSignature().getName());
Object result = joinPoint.proceed();
System.out.println("Around - After method: " + joinPoint.getSignature().getName());
return result;
}
}


Пример сервиса:
@Service
public class UserService {
public String getUserById(Long id) {
System.out.println("Fetching user with ID: " + id);
return "User" + id;
}
}


#Java #Training #Spring #AOP