Следует ли явно прописывать зависимость CGLIB, если она не используется напрямую?

Ответ

Нет, не следует. Управление зависимостями должно быть минимальным и явным. CGLIB обычно является транзитивной зависимостью таких фреймворков, как Spring (для AOP) или Hibernate (для прокси lazy-сущностей).

Проблемы лишних зависимостей:

  • Увеличение размера артефакта.
  • Риск конфликтов версий.
  • Усложнение анализа уязвимостей (security scan).
  • Затруднённое понимание реальных зависимостей проекта.

Если CGLIB не требуется (например, в Spring используются только JDK Dynamic Proxies для интерфейсов), его можно исключить:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <exclusions>
        <exclusion>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Важно: Не исключайте CGLIB, если используете фичи, требующие наследования классов (например, @Configuration без интерфейсов, проксирование @Transactional на не-интерфейсных методах).

Ответ 18+ 🔞

Да ты посмотри, какой умный совет! Прям как в аптеке, блядь. «Управление зависимостями должно быть минимальным». Ну да, конечно, а жизнь должна быть стерильной, а код — девственным. Ёпта, мечты-мечты.

Слушай сюда, я тебе на пальцах, как Герасим немой, объясню. Вот представь: твой проект — это твоя хата. А CGLIB — это какой-то левый мужик, которого к тебе в гости притащил твой кореш Spring, когда заходил пивка попить. Ты этого мужика даже в глаза не видел, а он уже у тебя на кухне бутерброды жрёт, блядь.

И проблемы-то какие, а?

  • Размер артефакта увеличится. Ну, овердохуища, целых лишних 300 килобайт! Пиздец, свет клином сошёлся. Хотя, конечно, если ты на спутнике код гоняешь — тогда да, волнение ебать.
  • Конфликты версий. Вот это уже ближе к телу. Твой Spring тащит cglib:3.3.0, а какой-нибудь Hibernate-enhance-plugin из другого угла норовить подсунуть cglib:2.2.2. И пошла писать губерния, чувак. Один кричит «Муму!», другой мычит в ответ. В итоге всё накрывается медным тазом на старте.
  • Анализ уязвимостей усложняется. Это вообще песня. Приходит security-сканер, такой серьёзный дядя, и говорит: «У тебя тут в углу cglib 1999 года валяется, в нём дыра размером с мою жопу». А ты такой: «Да я его даже не звал! Это всё Spring!». А дядя: «Мне похуй. Уязвимость есть. Чини». И сидишь ты, ебашь эту проблему, которую сам не создавал. Чистый пиздец.

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

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <exclusions>
        <exclusion>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Сделал exclusion — и нет человека, нет проблем. Мужик ушёл, бутерброды целы.

НО! Тут главное — не обосраться, как тот самый Герасим. Не выгоняй CGLIB, если он тебе реально нужен. А нужен он, если:

  • Ты используешь @Configuration классы по-старинке, без интерфейсов. Spring будет наследоваться от них, чтобы проксировать вызовы бинов. Без CGLIB — получишь хуй с горы вместо конфигурации.
  • Вешаешь @Transactional или @Cacheable на обычные публичные методы класса (не интерфейса). Опять надо наследование, опять нужен CGLIB.

Выкинешь его в таком случае — и приложение встанет с таким выражением лица, будто его обосрали и не вытерли. Будет орать про BeanNotOfRequiredTypeException или что-то в этом духе.

Так что правило простое, блядь: Сначала подумай, потом исключай. А то получится как в той истории — «Я был мудак, блядь... неправильно сообщили, а хуй проверишь!». Не надо так.