← Назад к вопросам

От чего зависит CGLib?

1.0 Junior🔥 191 комментариев
#Docker, Kubernetes и DevOps

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Ответ: Зависимости CGLIB в Spring

Что такое CGLIB

CGLIB (Code Generation Library) — это библиотека для динамического создания подклассов Java классов на лету. Spring использует её для создания прокси-объектов при работе с @Transactional, @Async, аспектами и другими декораторами.

Основные зависимости

CGLIB зависит от следующих компонентов:

1. ASM

// pom.xml
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm</artifactId>
    <version>9.5</version>  // Требуется для работы CGLIB
</dependency>

ASM — это библиотека для манипуляции байт-кодом Java. CGLIB использует ASM для:

  • Анализа классов
  • Генерации нового байт-кода
  • Создания подклассов на основе существующих классов

Без ASM CGLIB не может работать, так как именно ASM предоставляет низкоуровневые инструменты для модификации байт-кода.

2. Java версия

CGLIB зависит от версии Java:

// CGLIB 3.x требует Java 8+
// CGLIB 4.x требует Java 11+

Разные версии CGLIB используют разные возможности:

  • Java 8 — базовая поддержка
  • Java 11+ — использование более новых API для генерации кода

3. Spring Framework

CGLIB автоматически подключается через зависимость на Spring Core:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>6.0.x</version>
    <!-- Включает CGLIB и ASM -->
</dependency>

Вы не обязаны явно добавлять CGLIB — Spring сам его подтягивает.

Когда CGLIB используется

Spring создает CGLIB прокси в следующих случаях:

// 1. Для @Transactional на классах
@Component
public class UserService {
    @Transactional
    public void saveUser(User user) {
        // Spring создаст прокси через CGLIB
    }
}

// 2. Для @Async
@Component
public class EmailService {
    @Async
    public void sendEmail(String to) {
        // CGLIB прокси для асинхронного вызова
    }
}

// 3. Для классов (не интерфейсов) с @Transactional
@Component
@Transactional
public class OrderService {
    // CGLIB создаст подкласс OrderService
}

JDK Proxy vs CGLIB

Spring использует CGLIB, когда не может использовать JDK Dynamic Proxy:

// ✅ JDK Proxy (не требует CGLIB)
public interface UserRepository {
    void save(User user);
}

@Component
public class UserRepositoryImpl implements UserRepository {
    @Transactional
    public void save(User user) {
        // JDK создаст прокси $Proxy0, реализующий интерфейс
    }
}

// ❌ Требует CGLIB
@Component
public class UserService {  // Класс, не интерфейс!
    @Transactional
    public void save(User user) {
        // CGLIB создаст подкласс UserService$$EnhancerByCGLIB
    }
}

Проблемы и решения

Проблема: CGLIB не может проксировать final классы

// ❌ Ошибка
@Component
public final class UserService {  // final!
    @Transactional
    public void save() {}
}
// Ошибка: Cannot proxy final class

Решение:

// ✅ Правильно
@Component
public class UserService {
    @Transactional
    public final void save() {}  // final можно ставить на метод
}

Проблема: CGLIB не может проксировать private методы

// ❌ @Transactional на private игнорируется
@Component
public class UserService {
    @Transactional
    private void internalSave() {}  // Не будет проксирована!
}

// ✅ Правильно
@Component
public class UserService {
    @Transactional
    public void save() {}
}

Явное включение CGLIB

В Spring Boot CGLIB используется по умолчанию, но вы можете явно настроить:

# application.properties
spring.aop.proxy-target-class=true  # Принудительно используй CGLIB вместо JDK

Резюме зависимостей

ЗависимостьНазначениеВерсия
ASMМанипуляция байт-кодом9.x
JavaRuntime окружение8+
Spring CoreПодключение CGLIB5.x+

CGLIB зависит прежде всего от ASM для генерации байт-кода и версии Java для совместимости с API генерации. Spring автоматически управляет этими зависимостями через spring-core.

От чего зависит CGLib? | PrepBro