Об изменении не всегда можно сказать, исполнение — это способность открывать дистанцию между людьми.
1. Спрос2. Анализ проблемы3. Посмотрите исходный код, чтобы решить проблему, что перехватчик не работает4. Принцип пустого интерцептора5. Думая о фреймворке Hibernate и Mybatis6. Резюме:
1. Спрос
После того, как система наберет клиентов, она создаст лид, а теперь необходимо расширить создание лидов
2. Анализ проблемы
По причинам исторических разработчиков абстракция сделана плохо, а логики для создания подсказок в коде много, теперь нужно сделать расширение к созданным подсказкам. Если вы найдете все блоки кода, которые создают подсказки для модификации, это будет очень утомительно.
В системе используется: архитектура SpringBoot+Hibernate.
Первоначально я хотел решить эту проблему с помощью фасетов, но нашел это довольно громоздким.
Когда я был в замешательстве, у меня было прозрение, есть ли какой-нибудь перехватчик в Hibernate. У Baidu есть этоEmptyInterceptor
перехватчик. Но судя по интернетуКонфигурация не вступает в силу.
3. Посмотрите исходный код, чтобы решить проблему, что перехватчик не работает
Вот как я решил эту проблему
Я пропускаюidea
Функция find нашла несколько применений в исходном коде.EmptyInterceptor
кодовый блок. Затем проверьте исходный код один за другим.
существуетSessionFactoryBuilderImpl
нашел подсказки в
this.interceptor = strategySelector.resolveDefaultableStrategy(
Interceptor.class,
configurationSettings.get( INTERCEPTOR ),//自定义的拦截器
EmptyInterceptor.INSTANCE//默认的拦截器
);
Здесь в процессе сборки SessionFactory он будет установлен здесьinterceptor
перехватчик. Вот простой режим стратегии.
Логика: если настроен пользовательский перехватчик, используйте пользовательский перехватчик. Если он не настроен, будет использоваться перехватчик по умолчанию.
configurationSettings.get( INTERCEPTOR )
Здесь берется конфигурационный ключ, соответствующий сконфигурированному перехватчику INTERCEPTOR.
String INTERCEPTOR = "hibernate.session_factory.interceptor";
То есть нам нужно использовать этот параметр ключа конфигурации при настройке пользовательского перехватчика.
#配置
hibernate.session_factory.interceptor=com.wsjia.ms.doApplication.util.SerialIntercpter
@Value("${hibernate.session_factory.interceptor}")
private String INTERCEPTOR;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
sessionFactoryBean.setPackagesToScan(ENTITYMANAGER_PACKAGES_TO_SCAN);
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", HIBERNATE_HBM2DDL_AUTO);
hibernateProperties.put("hibernate.session_factory.interceptor",INTERCEPTOR);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
return sessionFactoryBean;
}
4. Принцип пустого интерцептора
Сделав еще один шаг, я посмотрел, как работает перехватчик.
(1. Первый:LocalSessionFactoryBean
какFactoryBean
создастSessionFactory
Фабрика используется для созданияSession
Класс реализации SessionFactory: SessionFactoryImpl
public SessionFactory build() {
metadata.validate();
return new SessionFactoryImpl( metadata, buildSessionFactoryOptions() );
}
(2. Второй
Метод SessionFactoryImpl.openSession вызовет построитель сеансов.SessionBuilderImpl
Метод openSession, создайте сеанс, затем перехватчик будет установлен на сеанс
public Session openSession() {
log.tracef( "Opening Hibernate Session. tenant=%s, owner=%s", tenantIdentifier, sessionOwner );
final SessionImpl session = new SessionImpl(
connection,
sessionFactory,
sessionOwner,
getTransactionCoordinator(),
getJdbcCoordinator(),
getTransaction(),
getTransactionCompletionProcesses(),
autoJoinTransactions,
sessionFactory.settings.getRegionFactory().nextTimestamp(),
interceptor,
statementInspector,
flushBeforeCompletion,
autoClose,
connectionReleaseMode,
tenantIdentifier
);
for ( SessionEventListener listener : listeners ) {
session.getEventListenerManager().addListener( listener );
}
return session;
}
(3.session:
Давайте взглянем на метод SessionImpl.save.
@Override
public Serializable save(Object obj) throws HibernateException {
return save( null, obj );
}
@Override
public Serializable save(String entityName, Object object) throws HibernateException {
return fireSave( new SaveOrUpdateEvent( entityName, object, this ) );
}
private Serializable fireSave(SaveOrUpdateEvent event) {
errorIfClosed();
checkTransactionSynchStatus();
checkNoUnresolvedActionsBeforeOperation();
for ( SaveOrUpdateEventListener listener : listeners( EventType.SAVE ) ) {
listener.onSaveOrUpdate( event );
}
checkNoUnresolvedActionsAfterOperation();
return event.getResultId();
}
Давайте посмотрим на этот процесс сохранения:
- Оберните текущую сущность в событие SaveOrUpdateEvent.
- сделать несколько проверок
- перечислить
同步监听器
Метод onSaveOrUpdate, обрабатывающий событие сохранения. - вернуть идентификатор
Вызов перехватчика происходит в слушателе.AbstractSaveEventListener
protected boolean substituteValuesIfNecessary(
Object entity,
Serializable id,
Object[] values,
EntityPersister persister,
SessionImplementor source) {
//拦截器的调用
boolean substitute = source.getInterceptor().onSave(
entity,
id,
values,
persister.getPropertyNames(),
persister.getPropertyTypes()
);
}
В этот момент будет вызван наш пользовательский перехватчик.
5. Думая о фреймворке Hibernate и Mybatis
Мысли дальше: Hibernate против Mybatis
Прочитав исходный код Mybatis и немного Hibernate, я пришел к следующему выводу.
- Метод проектирования Mybatis и Hibernate: создание конфигурации персонализированной фабрики SessionFactory. Используйте фабрику для создания сеанса. В этом вопросе все примерно одинаковы.
- Мибатис: пройти
Executor
исполнитель для обработки CRUD - Спящий режим использует
同步监听器
Чтобы обработать операцию, создайте событие перед операцией, а затем вызовите прослушиватель для его обработки.
6. Резюме:
Какой бы сложной ни была структура, она организована по разделам синхронного кода. Пока вы овладеваете навыками чтения исходного кода, вы обнаружите, что дизайн нескольких фреймворков похож по назначению. Чтение исходного кода помогает нам лучше решать проблемы