LoadTimeWeaving в Spring Boot 1.4.3+ не работает после обновления с 1.4.2 - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть работающий проект Spring Boot с включенным LoadTimeWeaving. Когда я говорю Gradle использовать Spring Boot 1.4.3 (или выше) вместо 1.4.2, приложение больше не может запускаться, выдавая ошибку в виде:

Ошибка запуска ApplicationContext. [...] Вызвано:

_persistence_set также может быть _init () или что-то еще.

Исключение, насколько я понимаю, просто означает, что сущность (или суперкласс сущности) не была должным образом сплетена, и, следовательно, методы, которые должны быть вплетены в класс, не могут быть вызваны (например, _persistence_set (), _init ( ) так далее).

Я использовал аргумент -verbose: class для запуска моего проекта, который затем печатает каждый класс при его загрузке. Оказывается, в Spring Boot 1.4.2 (где все работает) объекты загружаются после инициализации LoadTimeWeaver, а в Spring Boot 1.4.3+ несколько классов абстрактных базовых объектов загружаются до этой точки. Это означает, что они не сотканы, когда они загружены, поскольку ткач не инициализирован, но они не будут сотканы после инициализации ткача, потому что они загружаются только один раз.

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

1 Ответ

0 голосов
/ 04 сентября 2018

Я пытался решить это в течение нескольких дней. Это то, что я обнаружил после отладки того, как Spring инициализирует контекст приложения (и с этим бины, ткач и т. Д.).

У нас было несколько классов @Configuration, которые определяли @Bean, которые были напечатаны с помощью сущностей. Как это:

@Configuration
public class UserModuleConfiguration {

    @Bean
    public BasePresenter<EUser> userPresenter() {
        return new BasePresenter<EUser>() {
        };
    }
}

Когда я удалил сущность из возвращаемого типа этого метода, все работало. Обратите внимание, что поскольку существует более одной из этих конфигураций, предоставляющих BasePresenter для разных объектов, вы должны использовать @Qualifier или просто создавать их экземпляры самостоятельно. Как то так:

@Configuration
public class UserModuleConfiguration {

    @Bean("userPresenter")
    public BasePresenter<?> userPresenter() {
        return new BasePresenter<EUser>() {
        };
    }
}

или

@Component
public class UserPresenter<EUser> extends BasePresenter{

}

Внутренне, перед тем как начать «оценивать» конфигурации, пружина определяет, какие бины доступны, чтобы определить, должны ли быть загружены определенные конфигурации (см. @ConditionalOnMissingBean и т. П.), И, очевидно, в процессе выполнения этой пружины загружаются некоторые из супер классы сущностей. Я просто хотел оставить это здесь, потому что я действительно не нашел ничего об этой возможной причине, и мне потребовались целые годы, чтобы найти это.

...