Spring Framework
даJavaСамый популярный в экосистемеиз Один из фреймворков с открытым исходным кодом,Для создания приложений корпоративного уровня。один из могущественныхиз ФункцияSpring
Контейнерами можно управлятьJava Bean
изжизненный цикл,Но иногда необходимо динамически регистрироваться и обновляться во время выполнения.Bean
,В этой статье объясняется, как использовать эту функцию.
в некоторых случаях,Возможно, нам придется добавлять или обновлять динамически во время работы приложения.Spring Bean
,например,Иногда мы храним информацию у определенных третьих лиц в базах данных.,Чтобы обеспечить одноэлементный характер определенного Служитьиз,Вы не можете каждый раз динамически создавать Служитьобъект.,В это время был сформирован“Необходимо зарегистрироваться какBean
И необходимо поддерживать динамические обновленияBean
”изнуждаться。 Это можно использовать для подключаемых систем, модульных приложений или сценариев, в которых бизнес-правила необходимо обновить без перезапуска приложения.
Функциявыполнитьзависит отSpring
поставлятьизApplicationContextAware
интерфейс,На его основе можновыполнитьодинSpring
контекст,Spring
контекст Часто, когда нам нужно быть в АфрикеBean
издобрый ЗалезайSpring Bean
изиспользуется, когда。
СтроитьодиндобрыйSpringContext
ивыполнитьSpringпоставлятьизApplicationContextAware
интерфейс,ипереписатьset ApplicationContext
метод,можно получитьSpring
изконтекстобъектApplicationContext
。
@Override
public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
SpringContext.context = applicationContext;
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
throw new RuntimeException("applicationContext is not ConfigurableApplicationContext, can not register singleton bean");
}
SpringContext.configurableContext = (ConfigurableApplicationContext) applicationContext;
}
используйте этот метод,мы можемвыполнитьодинконтекстинструментдобрый,следующее:
import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.*;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
* @author JanYork
* @version 1.0.0
* @date 2023/10/20
* @description Весенний контекст
* @since 1.0.0
*/
@Component
public class SpringContext implements ApplicationContextAware, EnvironmentAware {
@Getter
private volatile static ApplicationContext context;
private volatile static Environment environment;
private volatile static ConfigurableApplicationContext configurableContext;
@Override
public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
SpringContext.context = applicationContext;
if (!(applicationContext instanceof ConfigurableApplicationContext)) {
throw new RuntimeException("applicationContext is not ConfigurableApplicationContext, can not register singleton bean");
}
SpringContext.configurableContext = (ConfigurableApplicationContext) applicationContext;
}
@Override
public void setEnvironment(@NotNull Environment environment) {
SpringContext.environment = environment;
}
/**
* Получить бобы
*
* @param bean beanизclass
* @param <T> тип боба
* @return bean
*/
public static <T> T getBean(Class<T> bean) {
return context.getBean(bean);
}
public static <T> T getBean(String beanName, Class<T> bean) {
return context.getBean(beanName, bean);
}
public static <T> T getBeanOrNull(Class<T> bean) {
try {
return context.getBean(bean);
} catch (Exception e) {
return null;
}
}
/**
* получать Конфигурация
*
* @param key Конфигурацияkey
* @return Конфигурацияvalue
*/
public static String getConfig(String key) {
return environment.getProperty(key);
}
public static String getConfigOrElse(String mainKey, String slaveKey) {
String ans = environment.getProperty(mainKey);
if (ans == null) {
return environment.getProperty(slaveKey);
}
return ans;
}
/**
* получать Конфигурация
*
* @param key Конфигурацияизkey
* @param val значение по умолчанию, если Конфигурация не существует
* @return Конфигурацияизvalue
*/
public static String getConfig(String key, String val) {
return environment.getProperty(key, val);
}
/**
* Публикуйте новости о мероприятии
*
* @param event событие
*/
public static void publishEvent(ApplicationEvent event) {
context.publishEvent(event);
}
}
Следует отметить, что из,этотконтекстинструментдобрый Сам должендаодинBean
,Нужно добавить@Component
аннотация.
Далее нам нужно узнать больше оConfigurableApplicationContext
этотдобрый。 вышеизконтекстинструментдобрыйсередина,я не толькополучатьдобрыйSpring Context
,я тоже написалSpringContext.configurableContext = (ConfigurableApplicationContext) applicationContext;
Этот код,глазизда Что Шерстяная ткань? Давайте сначала декомпилируем его и посмотрим на его исходный код.
Здесь мы можем увидеть,ConfigurableApplicationContext
интерфейсунаследованныйApplicationContext
интерфейс,так Я конвертирую напрямуюдобрыйформадабез проблемиз,Что касается того, зачем конвертировать,дапотому чтоConfigurableApplicationContext
интерфейссерединаиметьодиндополнительныйизметод Нужно использовать。
ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
ConfigurableListableBeanFactory getBeanFactory()
метод,можно получитьодинConfigurableListableBeanFactory
добрый。 этотметодизфинальныйвыполнитьдасуществоватьGenericApplicationContext
добрый。
И вGenericApplicationContext
добрыйсередина,Конструкторследующее:
public GenericApplicationContext() {
this.customClassLoader = false;
this.refreshed = new AtomicBoolean();
this.beanFactory = new DefaultListableBeanFactory();
}
иthis.beanFactory = new DefaultListableBeanFactory();
этоткод,На самом деледасуществовать初始化одинпо умолчаниюизBean
Экземпляр фабрики,иэтот Пример ТочнодадействоватьSpring IOC
изодинключ。 существоватьэтотдобрыйсередина还存существоватьполучатьэтотBean
Экземпляр фабрикиизметод:
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
Примечание:
ConfigurableListableBeanFactorys
даDefaultListableBeanFactory
изотецдобрый。
так,существоватьконтекстинструментдобрыйсередина,мы можемпроходитьполучатьприезжатьизConfigurableApplicationContext
ПриходитьполучатьприезжатьConfigurableListableBeanFactory
,оти达приезжать插手SpringBean
Примериз Примечание Регистрация и уничтожение。
ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
DefaultListableBeanFactory
даConfigurableListableBeanFactory
извыполнить,мы можем ПроверятьDefaultListableBeanFactory
серединаиметь关Bean
действоватьиз Исходный код。 иDefaultListableBeanFactory
сновада Самый оригинальныйBean
фабрикаизвыполнить,так Он может напрямуюBean
руководитьдействовать,мы можемвзгляни на этоиздобрыйкартина,Должен сказатьSpring
из Исходный кодиз Реальный структурный дизайнизда Очень тонкий。
Это немного многословно, но я надеюсь, что, зная, как его использовать, я также смогу знать, откуда взялся этот метод, чтобы иметь более глубокое понимание.,Теперь приступим к делу,Как использоватьConfigurableListableBeanFactory
идти Примечание Регистрация и уничтожениеBean
Шерстяная ткань? ConfigurableListableBeanFactory
存существовать以下метод,используется для Примечание Регистрация и уничтожениеBean
。
// author JanYork
ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
beanFactory.registerSingleton(); //Параметры не отображаются
beanFactory.destroyBean(); //Параметры не отображаются
/**
* Регистрация одноэлементного компонента
*
* @param beanName имя
* @param singletonObject Пример объекта
*/
public static void registerSingleton(String beanName, Object singletonObject) {
ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
// Если он уже существует, сначала уничтожьте его.
if (beanFactory.containsSingleton(beanName)) {
unregisterSingleton(beanName);
}
beanFactory.registerSingleton(beanName, singletonObject);
}
/**
* Регистрация одноэлементного компонента
*
* @param beanClass добрый
* @param singletonObject Пример объекта
*/
public static void registerSingleton(Class<?> beanClass, Object singletonObject) {
String beanName = beanClass.getName();
ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
// Если он уже существует, сначала уничтожьте его.
if (beanFactory.containsSingleton(beanName)) {
unregisterSingleton(beanClass);
}
beanFactory.registerSingleton(beanName, singletonObject);
}
/**
* Отменить регистрациюBean
*
* @param beanName имя
*/
public static void unregisterSingleton(String beanName) {
ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
if (beanFactory instanceof DefaultListableBeanFactory defaultListableBeanFactory) {
// Сначала обязательно уничтожьте экземпляр компонента (если экземпляр компонента является одноэлементным).
if (defaultListableBeanFactory.containsSingleton(beanName)) {
defaultListableBeanFactory.destroySingleton(beanName);
}
// Затем удалите определение компонента из реестра определений контейнера.
if (defaultListableBeanFactory.containsBeanDefinition(beanName)) {
defaultListableBeanFactory.removeBeanDefinition(beanName);
}
}
}
/**
* Отменить регистрациюBean
*
* @param beanClass добрый
*/
public static void unregisterSingleton(Class<?> beanClass) {
String beanName = beanClass.getName();
ConfigurableListableBeanFactory beanFactory = configurableContext.getBeanFactory();
if (beanFactory instanceof DefaultListableBeanFactory defaultListableBeanFactory) {
// Сначала обязательно уничтожьте экземпляр компонента (если экземпляр компонента является одноэлементным).
if (defaultListableBeanFactory.containsSingleton(beanName)) {
defaultListableBeanFactory.destroySingleton(beanName);
}
// Затем удалите определение компонента из реестра определений контейнера.
if (defaultListableBeanFactory.containsBeanDefinition(beanName)) {
defaultListableBeanFactory.removeBeanDefinition(beanName);
}
}
}
Примечание:Я здесьизразрушатьметод没иметь直接использовать
beanFactory.destroyBean()
,Потому что мне может понадобиться что-то сделать при уничтожении,Я здесьиспользоватьdefaultListableBeanFactory
уничтожитьBean
,он разделен на две части,одиндаразрушатьBean
из Пример,одиндаразрушатьBean
из Примечаниеинформация о реестре。
ИзтакбытьbeanFactory(ConfigurableListableBeanFactory)
конвертировать вDefaultListableBeanFactory
дапотому чтоDefaultListableBeanFactory
выполнить ПонятноDefaultSingletonBeanRegistry
,В противном случае просто используйтеConfigurableListableBeanFactory
онда无法использоватьdefaultListableBeanFactory
серединаизcontainsSingleton
、destroySingleton
、containsBeanDefinition
、removeBeanDefinition
методиз,Конкретные причины можно посмотретьдобрыйкартина。
OK,Итак, с помощью этих методов,мы можемпроходитьконтекстинструментдобрый Приходите и вмешайтесь напрямуюBean
из Примечание Регистрация и уничтожение,Итак, мы можемвыполнитьдинамичныйиз Перейти к обновлениюBean
Приходить,например: определенное текстовое сообщение Служитьиз Ключ и ключ хранятся в базе данных.,Spring
База данных будет прочитана при запуске программы.середина Короткое сообщение Служить Конфигурацияиз Сопутствующая информация по инициализации SMSСлужитьиз Пример объекта,При вызове смены СМС Служить в базе данных из Конфигурация,мы можемсуществовать修改后调用контекстизBean
разрушать与Примечаниекнигаметод,выполнитьBean
издинамичныйвозобновлять。
Если вы используете микросервисы, в этом нет необходимости, поскольку в центре регистрации и центре конфигурации в основном будет выполняться динамическая настройка и динамическое обновление.Bean
определенные операции, напримерNacos
из@RefreshScope
аннотация.
Введение в эту статью Понятно Как использоватьSpring
выполнитьдинамичный Примечаниекнига和возобновлятьBean
из Функция。СоздаваяBean
определениеипоставь это ПримечаниекнигаприезжатьSpring
контейнерсередина,мы можемсуществовать应用程序运行时динамичныйуправлятьBean
。 Это полезно для создания гибких приложений и систем плагинов. пожалуйста Примечаниезначение,Динамическая регистрация и обновление Beans — мощная функция.,но также нужноИспользуйте с осторожностью,чтобы избежать сложности и проблем с производительностью. Выберите, использовать ли этот метод, исходя из реальных потребностей и сценариев. Надеюсь, эта статья будет вам полезна.