@RefreshScope
public class App {
}
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
// 作用域为刷新作用域
@Scope("refresh")
@Documented
public @interface RefreshScope注解 {
/**
* 作用域代理的模式,默认为CGLIB
*/
@AliasFor(annotation = Scope.class)
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;
}
// 导入刷新配置的核心处理类
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(ConfigurationPropertiesBindingPostProcessor.class)
public class ConfigurationPropertiesRebinderAutoConfiguration implements ApplicationContextAware, SmartInitializingSingleton {
// Spring上下文
private ApplicationContext context;
// 创建ConfigurationPropertiesBeans的Bean,它保存了所有标注在当前上下文中所有的ConfigurationProperties类
@Bean
@ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
public static ConfigurationPropertiesBeans configurationPropertiesBeans() {
return new ConfigurationPropertiesBeans();
}
// 注入将指定ConfigurationProperties类进行重新绑定
@Bean
@ConditionalOnMissingBean(search = SearchStrategy.CURRENT)
public ConfigurationPropertiesRebinder configurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {
ConfigurationPropertiesRebinder rebinder = new ConfigurationPropertiesRebinder(beans);
return rebinder;
}
// 所有的Bena都初始化完成
@Override
public void afterSingletonsInstantiated() {
// 如果存在父容器
if (this.context.getParent() != null) {
// 获取ConfigurationPropertiesRebinder该Bean
ConfigurationPropertiesRebinder rebinder = this.context.getBean(ConfigurationPropertiesRebinder.class);
// 获取父容器中所有的Bean进行重新加载
for (String name : this.context.getParent().getBeanDefinitionNames()) {
rebinder.rebind(name);
}
}
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RefreshScope.class)
@ConditionalOnProperty(name = RefreshAutoConfiguration.REFRESH_SCOPE_ENABLED, matchIfMissing = true)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@EnableConfigurationProperties(RefreshAutoConfiguration.RefreshProperties.class)
public class RefreshAutoConfiguration {
// 注册刷新作用域
@Bean
@ConditionalOnMissingBean(RefreshScope.class)
public static RefreshScope refreshScope() {
return new RefreshScope();
}
// 配置数据上下文的刷新器,它负责刷新该作用域下的所有bean
@Bean
@ConditionalOnMissingBean
@ConditionalOnBootstrapDisabled
public ConfigDataContextRefresher configDataContextRefresher(ConfigurableApplicationContext context, RefreshScope scope, RefreshProperties properties) {
return new ConfigDataContextRefresher(context, scope, properties);
}
/**
* {@link com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListener(java.lang.String, java.lang.String)}
* 配置刷新的监听器,该RefreshEvent是由对应的配置中心发布的事件,例如Nacos发生匹配变化的时候,就会触发一个RefreshEvent事件
*/
@Bean
public RefreshEventListener refreshEventListener(ContextRefresher contextRefresher) {
return new RefreshEventListener(contextRefresher);
}
}
// 配置数据上下文的刷新器,它负责刷新该作用域下的所有bean
public class ConfigDataContextRefresher extends ContextRefresher implements ApplicationListener<ContextRefreshedWithApplicationEvent> {
// Spring上下文对象
private ConfigurableApplicationContext context;
// 刷新作用域的实现
private RefreshScope scope;
// SpringBoot的配置为了
private SpringApplication application;
@Override
public void onApplicationEvent(ContextRefreshedWithApplicationEvent event) {
application = event.getSpringApplication();
}
// 更新环境对象,返回一个新的环境对象
@Override
protected void updateEnvironment() {
// 拷贝一份上下文环境存在的属性对象
StandardEnvironment environment = copyEnvironment(getContext().getEnvironment());
ConfigurableBootstrapContext bootstrapContext = getContext().getBeanProvider(ConfigurableBootstrapContext.class).getIfAvailable(DefaultBootstrapContext::new);
// 加载所有的EnvironmentPostProcessor后置处理器
List<String> classNames = SpringFactoriesLoader.loadFactoryNames(EnvironmentPostProcessor.class, getClass().getClassLoader());
Instantiator<EnvironmentPostProcessor> instantiator = new Instantiator<>(EnvironmentPostProcessor.class,
(parameters) -> {
parameters.add(DeferredLogFactory.class, logFactory);
parameters.add(Log.class, logFactory::getLog);
parameters.add(ConfigurableBootstrapContext.class, bootstrapContext);
parameters.add(BootstrapContext.class, bootstrapContext);
parameters.add(BootstrapRegistry.class, bootstrapContext);
});
// 实例化所有EnvironmentPostProcessor的类
List<EnvironmentPostProcessor> postProcessors = instantiator.instantiate(classNames);
for (EnvironmentPostProcessor postProcessor : postProcessors) {
// 对拷贝的环境对象进行后置处理操作
postProcessor.postProcessEnvironment(environment, application);
}
// 如果包含refreshArgs属性,将该属性移除
if (environment.getPropertySources().contains(REFRESH_ARGS_PROPERTY_SOURCE)) {
environment.getPropertySources().remove(REFRESH_ARGS_PROPERTY_SOURCE);
}
// 获取环境对象中的所有属性
MutablePropertySources target = getContext().getEnvironment().getPropertySources();
String targetName = null;
// 保持属性的顺序
for (PropertySource<?> source : environment.getPropertySources()) {
String name = source.getName();
if (target.contains(name)) {
targetName = name;
}
if (!this.standardSources.contains(name)) {
if (target.contains(name)) {
target.replace(name, source);
} else {
if (targetName != null) {
target.addAfter(targetName, source);
targetName = name;
} else {
target.addFirst(source);
targetName = name;
}
}
}
}
}
// 刷新配置以及对应的配置为了
public synchronized Set<String> refresh() {
// 刷新环境对象
Set<String> keys = this.refreshEnvironment();
// 刷新标注了@RefreshScope的类
this.scope.refreshAll();
return keys;
}
// 刷新环境对象,返回发生变化的属性
public synchronized Set<String> refreshEnvironment() {
Map<String, Object> before = extract(this.context.getEnvironment().getPropertySources());
// 更新环境对象,返回一个新的环境对象
this.updateEnvironment();
// 获取发生变化的属性名
Set<String> keys = this.changes(before, extract(this.context.getEnvironment().getPropertySources())).keySet();
/**发布一个事件,该事件会由{@link ConfigurationPropertiesRebinder#onApplicationEvent(EnvironmentChangeEvent)}处理,从而刷新标注了**/
this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys));
// 返回发生变化的属性
return keys;
}
// 将原始的属性与当前的属性做对比,提取出发生变化的属性
private Map<String, Object> changes(Map<String, Object> before, Map<String, Object> after) {
Map<String, Object> result = new HashMap<>();
for (String key : before.keySet()) {
if (!after.containsKey(key)) {
result.put(key, null);
} else if (!equal(before.get(key), after.get(key))) {
result.put(key, after.get(key));
}
}
for (String key : after.keySet()) {
if (!before.containsKey(key)) {
result.put(key, after.get(key));
}
}
return result;
}
}
@ManagedResource
public class RefreshScope extends GenericScope implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, Ordered {
// 刷新当前作用域的所有Bean
public void refreshAll() {
/**
* 创建该作用域Bean的流程{@link RefreshScope#get(String, ObjectFactory)}
*/
// 销毁所有refresh作用域的@Bean,下次需要发现该作用域没有缓存该Bean,则又会触发Bean的创建
super.destroy();
// 发布作用域刷新事件,这个事件我们自己可以监听的做一些事情
this.context.publishEvent(new RefreshScopeRefreshedEvent());
}
/**
* <pre>
* 获取Bean对象,如果Bean对象不存在,则创建Bean
* // 根据不同的作用域来创建对象
* if (mbd.isSingleton()) {
* // 从单例池中获取,不存在则创建
* sharedInstance = getSingleton(beanName, () -> {
* return createBean(beanName, mbd, args);
* });
* beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
* }
* else if (mbd.isPrototype()) {
* // 直接创建
* prototypeInstance = createBean(beanName, mbd, args);
* beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
* }
* // 其他作用域
* else {
* // 获取自定义作用域的Scope对象
* String scopeName = mbd.getScope();
* Scope scope = this.scopes.get(scopeName);
* // 调用Scope的get方法,从该作用域中获取Bean对象,如果不存在则创建对象
* {@link BeanLifecycleWrapper#get(String, ObjectFactory)}
* Object scopedInstance = scope.get(beanName, () -> {
* return createBean(beanName, mbd, args);
* });
* beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
* }
* </pre>
*/
// 自定义作用域的get方法,从指定位置返回该作用域的Bean对象,这个Bean对象由自己管理
@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
// 缓存当前Bean
BeanLifecycleWrapper value = this.cache.put(name, new BeanLifecycleWrapper(name, objectFactory));
// 加读写锁
this.locks.putIfAbsent(name, new ReentrantReadWriteLock());
try {
return value.getBean();
} catch (RuntimeException e) {
this.errors.put(name, e);
throw e;
}
}
}
// Bean的Scope生命周期包装类
public class BeanLifecycleWrapper {
// BeanName
private final String name;
// 创建Bean的工厂
private final ObjectFactory<?> objectFactory;
// Bean对象
private volatile Object bean;
// 销毁Bean执行的任务
/**
* 在创建的Bean的时候,如果Bean是DisposableBean类型,会自动注册一个任务,就是将该Bean执行所有的DestructionAwareBeanPostProcessor,处理一些销毁逻辑
* {@link AbstractBeanFactory#registerDisposableBeanIfNecessary(String, Object, RootBeanDefinition)}
*/
private Runnable callback;
BeanLifecycleWrapper(String name, ObjectFactory<?> objectFactory) {
this.name = name;
this.objectFactory = objectFactory;
}
public String getName() {
return this.name;
}
public void setDestroyCallback(Runnable callback) {
this.callback = callback;
}
// 获取Bean对象
public Object getBean() {
// 是否存在Bean对象
if (this.bean == null) {
synchronized (this.name) {
// 使用对象工厂创建Bean对象
if (this.bean == null) {
// 保存Bean对象
this.bean = this.objectFactory.getObject();
}
}
}
return this.bean;
}
// 销毁Bean对象
public void destroy() {
// 如果没有设置销毁时需要执行的任务,则不处理任何东西
if (this.callback == null) {
return;
}
synchronized (this.name) {
// 执行指定的销毁任务
Runnable callback = this.callback;
if (callback != null) {
callback.run();
}
// 清空当前Bean对象
this.callback = null;
this.bean = null;
}
}
}
public class GenericScope implements Scope, BeanFactoryPostProcessor, BeanDefinitionRegistryPostProcessor, DisposableBean {
// 所有继承该类的作用域保存对应Bean的缓存对象
private BeanLifecycleWrapperCache cache = new BeanLifecycleWrapperCache(new StandardScopeCache());
// 销毁对象
@Override
public void destroy() {
// 清空所有该作用域的缓存Bean
Collection<BeanLifecycleWrapper> wrappers = this.cache.clear();
// 遍历所有该作用域的Bean的包装对象
for (BeanLifecycleWrapper wrapper : wrappers) {
// 调用每一个Bean包装器的销毁方法
wrapper.destroy();
}
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
// 注册当前作用域为refresh
beanFactory.registerScope(this.name, this);
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 获取所有的Bean
for (String name : registry.getBeanDefinitionNames()) {
BeanDefinition definition = registry.getBeanDefinition(name);
if (definition instanceof RootBeanDefinition root) {
// 如果是作用域代理的Bean
if (root.getDecoratedDefinition() != null && root.hasBeanClass() && root.getBeanClass() == ScopedProxyFactoryBean.class) {
// 并且当前Bean的作用域正好是refresh
if (getName().equals(root.getDecoratedDefinition().getBeanDefinition().getScope())) {
// 修改当前Bean的BeanClass,增强一下,从ScopedProxyFactoryBean变成LockedScopedProxyFactoryBean
// 它是继承ScopedProxyFactoryBean,就是在执行的过程中添加了读写锁
root.setBeanClass(LockedScopedProxyFactoryBean.class);
// 添加构造参数
root.getConstructorArgumentValues().addGenericArgumentValue(this);
root.setSynthetic(true);
}
}
}
}
}
}
/**
* {@link com.alibaba.cloud.nacos.refresh.NacosContextRefresher#registerNacosListener(java.lang.String, java.lang.String)}
* 配置刷新的监听器,该RefreshEvent是由对应的配置中心发布的事件,例如Nacos发生匹配变化的时候,就会触发一个RefreshEvent事件
*/
public class RefreshEventListener implements SmartApplicationListener {
// 配置数据上下文的刷新器
private ConfigDataContextRefresher refresh;
// 配置是否就绪
private AtomicBoolean ready = new AtomicBoolean(false);
public RefreshEventListener(ContextRefresher refresh) {
this.refresh = refresh;
}
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationReadyEvent.class.isAssignableFrom(eventType) || RefreshEvent.class.isAssignableFrom(eventType);
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationReadyEvent) {
// 标记已就绪
this.ready.compareAndSet(false, true);
}
if (event instanceof RefreshEvent) {
// 已就绪才会处理
if (this.ready.get()) {
// 使用配置数据的上下文对象进行刷新
Set<String> keys = this.refresh.refresh();
}
}
}
}
@Component
public class ConfigurationPropertiesBeans implements BeanPostProcessor, ApplicationContextAware {
// 标注了ConfigurationProperties的Bean对象
private Map<String, ConfigurationPropertiesBean> beans = new HashMap<>();
// Spring上下文
private ApplicationContext applicationContext;
// Bean工厂
private ConfigurableListableBeanFactory beanFactory;
// 刷新作用域
private String refreshScope;
// 刷新作用域是否初始化了
private boolean refreshScopeInitialized;
// 父容器中的ConfigurationPropertiesBeans
private ConfigurationPropertiesBeans parent;
// 初始化当前上下文中父容器的配置类ConfigurationProperties的Bean对象
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
if (applicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
}
AutowireCapableBeanFactory bf = applicationContext.getParent().getAutowireCapableBeanFactory();
// 如果存在父容器
if (applicationContext.getParent() != null && bf instanceof ConfigurableListableBeanFactory listable) {
// 从父容器中获取获取ConfigurationPropertiesBeans
String[] names = listable.getBeanNamesForType(ConfigurationPropertiesBeans.class);
// 如果只存在一个
if (names.length == 1) {
// 将该父容器中的ConfigurationPropertiesBeans保存
this.parent = (ConfigurationPropertiesBeans) listable.getBean(names[0]);
// 将父容器中的ConfigurationProperties的Bean对象保存
this.beans.putAll(this.parent.beans);
}
}
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 判断容器中的bean是不是refresh作用域
// 如果是,不处理
if (this.isRefreshScoped(beanName)) {
return bean;
}
// 如果不是refresh作用域,获取执行beanName的Bean对象,标注了ConfigurationProperties才会返回对象
// 如果不存在ConfigurationProperties注解,返回null
ConfigurationPropertiesBean propertiesBean = ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName);
// 如果是属性配置Bean
if (propertiesBean != null) {
// 保存当前配置Bean信息
this.beans.put(beanName, propertiesBean);
}
return bean;
}
// 判断容器中的bean是不是refresh作用域
private boolean isRefreshScoped(String beanName) {
// 如果刷新作用域为空(默认)并且没有被初始化过
if (this.refreshScope == null && !this.refreshScopeInitialized) {
// 开始初始化,标记初始化
this.refreshScopeInitialized = true;
// 遍历当前容器中的保存的所有作用域(例如,单例,原型,会话等等
for (String scope : this.beanFactory.getRegisteredScopeNames()) {
// 从容器中获取RefreshScope的Bean对象,如果当前作用域是RefreshScope,则保存该作用域
if (this.beanFactory.getRegisteredScope(scope) instanceof org.springframework.cloud.context.scope.refresh.RefreshScope) {
this.refreshScope = scope;
break;
}
}
}
// 如果beanName为空或者没找到RefreshScope的Bean,表示不是RefreshScope
if (beanName == null || this.refreshScope == null) {
return false;
}
// 如果当前Bean工厂包含指定的Bean,并且该Bean的作用域正是refresh(该Bean标注了@RefreshScope),返回true
return this.beanFactory.containsBeanDefinition(beanName) && this.refreshScope.equals(this.beanFactory.getBeanDefinition(beanName).getScope());
}
// 获取所有标注了ConfigurationProperties的Bean对象的BeanName
public Set<String> getBeanNames() {
return new HashSet<>(this.beans.keySet());
}
}
// 配置属性Bean的重新绑定器
@Component
@ManagedResource
public class ConfigurationPropertiesRebinder implements ApplicationContextAware, ApplicationListener<EnvironmentChangeEvent> {
// 需要重新绑定的配置类
private ConfigurationPropertiesBeans beans;
// Spring上下文对象
private ApplicationContext applicationContext;
// 重新绑定过程中的异常
private Map<String, Exception> errors = new ConcurrentHashMap<>();
// 需要将哪些配置Bean进行重新绑定
public ConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {
this.beans = beans;
}
// 重新绑定所有配置类
@ManagedOperation
public void rebind() {
// 清空所有的异常信息
this.errors.clear();
// 遍历当前需要重新绑定的配置类Bean名称
for (String name : this.beans.getBeanNames()) {
// 重新绑定
this.rebind(name);
}
}
// 重新绑定指定配置类
@ManagedOperation
public boolean rebind(String name) {
// 如果当前名称不在需要重新绑定的名单中,不处理
if (!this.beans.getBeanNames().contains(name)) {
return false;
}
ApplicationContext appContext = this.applicationContext;
// 遍历所有层级的Spring上下文
while (appContext != null) {
// 如果包含该配置Bean,进行重新绑定
if (appContext.containsLocalBean(name)) {
return rebind(name, appContext);
}
// 如果当前容器不包含当前配置Bean,则查找父容器
else {
appContext = appContext.getParent();
}
}
return false;
}
// 根据指定类型绑定
public boolean rebind(Class type) {
// 获取指定类型的配置Bean
String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.applicationContext, type);
if (beanNamesForType.length > 0) {
// 获取到该Bean最原始的BeanName,因为该Bean可能设置了作用域代理
String name = beanNamesForType[0];
// 如果是作用域代理的Bean
if (ScopedProxyUtils.isScopedTarget(name)) {
// 获取最原始的bean名称,因为作用域代理的beanName经过加工
name = ScopedProxyUtils.getOriginalBeanName(name);
}
// 开始绑定
return rebind(name, this.applicationContext);
}
return false;
}
// 真正的开始查询绑定
private boolean rebind(String name, ApplicationContext appContext) {
try {
// 获取需要绑定的Bean
Object bean = appContext.getBean(name);
// 获取到原始对象
if (AopUtils.isAopProxy(bean)) {
bean = ProxyUtils.getTargetObject(bean);
}
if (bean != null) {
// 如果设置了不支持刷新,不处理
if (getNeverRefreshable().contains(bean.getClass().getName())) {
return false;
}
// 销毁该Bean
appContext.getAutowireCapableBeanFactory().destroyBean(bean);
// 重新初始化该Bean
appContext.getAutowireCapableBeanFactory().initializeBean(bean, name);
return true;
}
} catch (RuntimeException e) {
// 保存绑定的异常信息
this.errors.put(name, e);
throw e;
} catch (Exception e) {
this.errors.put(name, e);
throw new IllegalStateException("Cannot rebind to " + name, e);
}
return false;
}
// 不支持刷新
@ManagedAttribute
public Set<String> getNeverRefreshable() {
String neverRefresh = this.applicationContext.getEnvironment().getProperty("spring.cloud.refresh.never-refreshable", "com.zaxxer.hikari.HikariDataSource");
return StringUtils.commaDelimitedListToSet(neverRefresh);
}
@ManagedAttribute
public Set<String> getBeanNames() {
return new HashSet<>(this.beans.getBeanNames());
}
// 如何监听到环境对象发生了改变,需要重新绑定
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
// 在配置属性发生改变的时候,会发布这个事件
/**
* {@link ConfigDataContextRefresher#refreshEnvironment}
*/
if (this.applicationContext.equals(event.getSource()) || event.getKeys().equals(event.getSource())) {
this.rebind();
}
}
}
06-06
5134
04-20
1524
01-27
517
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交