/** * Convenience annotation to put a <code>@Bean</code> definition in * {@link org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}. * Beans annotated this way can be refreshed at runtime and any components that are using * them will get a new instance on the next method call, fully initialized and injected * with all dependencies. * * @堆代码 duidaima.com * */ @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Scope("refresh") @Documented public @interface RefreshScope { /** * @see Scope#proxyMode() * @return proxy mode */ ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; }.上面是RefreshScope的源码,该注解被@Scope注解使用,@Scope用来比较Spring Bean的作用域,具体使用参考相关文章。
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { protected < T > T doGetBean( String name, @Nullable Class < T > requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { // 堆代码 duidaima.com // 如果scope是单例的情况, 这里不进行分析 if (mbd.isSingleton()) { ..... } // 如果scope是prototype的情况, 这里不进行分析 else if (mbd.isPrototype()) { ...... } // 如果scope是其他的情况,本例中是reresh else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean '" + beanName + "'"); } // 获取refresh scope的实现类RefreshScope,这个类在哪里注入,我们后面讲 Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { // 这边是获取bean,调用的是RefreshScope中的的方法 Object scopedInstance = scope.get(beanName, () - > { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } catch (BeansException ex) { beanCreation.tag("exception", ex.getClass().toString()); beanCreation.tag("message", String.valueOf(ex.getMessage())); cleanupAfterBeanCreationFailure(beanName); throw ex; } finally { beanCreation.end(); } } return adaptBeanInstance(name, beanInstance, requiredType); } }2.RefreshScope继承成了GenericScope类,最终调用的的是GenericScope的get方法
public class GenericScope implements Scope, BeanFactoryPostProcessor, BeanDefinitionRegistryPostProcessor, DisposableBean {@ Override public Object get(String name, ObjectFactory <? > objectFactory) { // 将bean添加到缓存cache中 BeanLifecycleWrapper value = this.cache.put(name, new BeanLifecycleWrapper(name, objectFactory)); this.locks.putIfAbsent(name, new ReentrantReadWriteLock()); try { // 调用下面的getBean方法 return value.getBean(); } catch (RuntimeException e) { this.errors.put(name, e); throw e; } } private static class BeanLifecycleWrapper { public Object getBean() { // 如果bean为空,则创建bean if (this.bean == null) { synchronized(this.name) { if (this.bean == null) { this.bean = this.objectFactory.getObject(); } } } // 否则返回之前创建好的bean return this.bean; } } }小结:
public class RefreshEventListener implements SmartApplicationListener { ........ public void handle(RefreshEvent event) { if (this.ready.get()) { // don't handle events before app is ready log.debug("Event received " + event.getEventDesc()); // 会调用refresh方法,进行刷新 Set < String > keys = this.refresh.refresh(); log.info("Refresh keys changed: " + keys); } } } // 这个是ContextRefresher类中的刷新方法 public synchronized Set < String > refresh() { // 刷新spring的envirionment 变量配置 Set < String > keys = refreshEnvironment(); // 刷新其他scope this.scope.refreshAll(); return keys; } refresh方法最终调用destroy方法, 清空之前缓存的bean public class RefreshScope extends GenericScope implements ApplicationContextAware, ApplicationListener < ContextRefreshedEvent > , Ordered { @ ManagedOperation(description = "Dispose of the current instance of all beans " + "in this scope and force a refresh on next method execution.") public void refreshAll() { // 调用父类的destroy super.destroy(); this.context.publishEvent(new RefreshScopeRefreshedEvent()); } } @ Override public void destroy() { List < Throwable > errors = new ArrayList < Throwable > (); Collection < BeanLifecycleWrapper > wrappers = this.cache.clear(); for (BeanLifecycleWrapper wrapper: wrappers) { try { Lock lock = this.locks.get(wrapper.getName()).writeLock(); lock.lock(); try { // 这里主要就是把之前的bean设置为null, 就会重新走createBean的流程了 wrapper.destroy(); } finally { lock.unlock(); } } catch (RuntimeException e) { errors.add(e); } } if (!errors.isEmpty()) { throw wrapIfNecessary(errors.get(0)); } this.errors.clear(); }总结