0%

IOC PostProcessor && Aware

TODO

@Bean && <bean/> 阶段

  • 用户使用注解或XML方式编写注册Bean

  • Spring通过BeanDefinitionReader将Bean解析成BeanDefinition BeanDefinitionRegistry.registry注入容器?只注入几个Loader?

    • AnnotatedBeanDefinitionReader
    • XmlBeanDefinitionReader
    • GroovyBeanDefinitionReader
    • @Deprecated PropertiesBeanDefinitionReader
  • 执行位置

    • org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String…)

      ->

      org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])

      ->

      org.springframework.boot.SpringApplication#run(java.lang.String…)

    • org.springframework.boot.SpringApplication#prepareContext

    • pringframework.boot.SpringApplication#load

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      /**
      * Create a new {@link BeanDefinitionLoader} that will load beans into the specified
      * {@link BeanDefinitionRegistry}.
      * @param registry the bean definition registry that will contain the loaded beans
      * @param sources the bean sources
      */
      BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {
      Assert.notNull(registry, "Registry must not be null");
      Assert.notEmpty(sources, "Sources must not be empty");
      this.sources = sources;
      this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
      this.xmlReader = (XML_ENABLED ? new XmlBeanDefinitionReader(registry) : null);
      this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null);
      this.scanner = new ClassPathBeanDefinitionScanner(registry);
      this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
      }

      /**
      * Factory method used to create the {@link BeanDefinitionLoader}.
      * @param registry the bean definition registry
      * @param sources the sources to load
      * @return the {@link BeanDefinitionLoader} that will be used to load beans
      */
      protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
      return new BeanDefinitionLoader(registry, sources);
      }


      /**
      * Load beans into the application context.
      * @param context the context to load beans into
      * @param sources the sources to load
      */
      protected void load(ApplicationContext context, Object[] sources) {
      if (logger.isDebugEnabled()) {
      logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
      }
      BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
      if (this.beanNameGenerator != null) {
      loader.setBeanNameGenerator(this.beanNameGenerator);
      }
      if (this.resourceLoader != null) {
      loader.setResourceLoader(this.resourceLoader);
      }
      if (this.environment != null) {
      loader.setEnvironment(this.environment);
      }
      loader.load();
      }

      //loader.load(); for循环进入,只有启动类
      private void load(Object source) {
      Assert.notNull(source, "Source must not be null");
      if (source instanceof Class<?>) {
      load((Class<?>) source);
      return;
      }
      if (source instanceof Resource) {
      load((Resource) source);
      return;
      }
      if (source instanceof Package) {
      load((Package) source);
      return;
      }
      if (source instanceof CharSequence) {
      load((CharSequence) source);
      return;
      }
      throw new IllegalArgumentException("Invalid source type " + source.getClass());
      }



      //load((Class<?>) source);
      private void load(Class<?> source) {
      if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
      // Any GroovyLoaders added in beans{} DSL can contribute beans here
      GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
      ((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());
      }
      if (isEligible(source)) {
      this.annotatedReader.register(source);
      }
      }

      //load((Resource) source);
      private void load(Resource source) {
      if (source.getFilename().endsWith(".groovy")) {
      if (this.groovyReader == null) {
      throw new BeanDefinitionStoreException("Cannot load Groovy beans without Groovy on classpath");
      }
      this.groovyReader.loadBeanDefinitions(source);
      }
      else {
      if (this.xmlReader == null) {
      throw new BeanDefinitionStoreException("Cannot load XML bean definitions when XML support is disabled");
      }
      this.xmlReader.loadBeanDefinitions(source);
      }
      }

      //load((Package) source);
      private void load(Package source) {
      this.scanner.scan(source.getName());
      }

      //load((CharSequence) source);
      private void load(CharSequence source) {
      String resolvedSource = this.scanner.getEnvironment().resolvePlaceholders(source.toString());
      // Attempt as a Class
      try {
      load(ClassUtils.forName(resolvedSource, null));
      return;
      }
      catch (IllegalArgumentException | ClassNotFoundException ex) {
      // swallow exception and continue
      }
      // Attempt as Resources
      if (loadAsResources(resolvedSource)) {
      return;
      }
      // Attempt as package
      Package packageResource = findPackage(resolvedSource);
      if (packageResource != null) {
      load(packageResource);
      return;
      }
      throw new IllegalArgumentException("Invalid source '" + resolvedSource + "'");
      }
    • org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      @Override
      public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {

      Assert.hasText(beanName, "Bean name must not be empty");
      Assert.notNull(beanDefinition, "BeanDefinition must not be null");

      if (beanDefinition instanceof AbstractBeanDefinition) {
      try {
      ((AbstractBeanDefinition) beanDefinition).validate();
      }
      catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
      "Validation of bean definition failed", ex);
      }
      }

      BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
      if (existingDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
      throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
      }
      else if (existingDefinition.getRole() < beanDefinition.getRole()) {
      // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
      if (logger.isInfoEnabled()) {
      logger.info("Overriding user-defined bean definition for bean '" + beanName +
      "' with a framework-generated bean definition: replacing [" +
      existingDefinition + "] with [" + beanDefinition + "]");
      }
      }
      else if (!beanDefinition.equals(existingDefinition)) {
      if (logger.isDebugEnabled()) {
      logger.debug("Overriding bean definition for bean '" + beanName +
      "' with a different definition: replacing [" + existingDefinition +
      "] with [" + beanDefinition + "]");
      }
      }
      else {
      if (logger.isTraceEnabled()) {
      logger.trace("Overriding bean definition for bean '" + beanName +
      "' with an equivalent definition: replacing [" + existingDefinition +
      "] with [" + beanDefinition + "]");
      }
      }
      this.beanDefinitionMap.put(beanName, beanDefinition);
      }
      else {
      if (hasBeanCreationStarted()) {
      // Cannot modify startup-time collection elements anymore (for stable iteration)
      synchronized (this.beanDefinitionMap) {
      this.beanDefinitionMap.put(beanName, beanDefinition);
      List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
      updatedDefinitions.addAll(this.beanDefinitionNames);
      updatedDefinitions.add(beanName);
      this.beanDefinitionNames = updatedDefinitions;
      removeManualSingletonName(beanName);
      }
      }
      else {
      // Still in startup registration phase
      this.beanDefinitionMap.put(beanName, beanDefinition);
      this.beanDefinitionNames.add(beanName);
      removeManualSingletonName(beanName);
      }
      this.frozenBeanDefinitionNames = null;
      }

      if (existingDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
      }
      else if (isConfigurationFrozen()) {
      clearByTypeCache();
      }
      }
    • GroovyBeanDefinitionReader, PropertiesBeanDefinitionReader, XmlBeanDefinitionReader会进行调用loadBeanDefinitions,AnnotatedBeanDefinitionReader没有实现BeanDefinitionReader接口,因为AnnotatedBeanDefinitionReader没有必要解析Spring的Resource类型,只要扫描jar包的class文件就可以

      org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      /**
      * Load bean definitions from the specified XML file.
      * @param encodedResource the resource descriptor for the XML file,
      * allowing to specify an encoding to use for parsing the file
      * @return the number of bean definitions found
      * @throws BeanDefinitionStoreException in case of loading or parsing errors
      */
      public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
      Assert.notNull(encodedResource, "EncodedResource must not be null");
      if (logger.isTraceEnabled()) {
      logger.trace("Loading XML bean definitions from " + encodedResource);
      }

      Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();

      if (!currentResources.add(encodedResource)) {
      throw new BeanDefinitionStoreException(
      "Detected cyclic loading of " + encodedResource + " - check your import definitions!");
      }

      try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
      InputSource inputSource = new InputSource(inputStream);
      if (encodedResource.getEncoding() != null) {
      inputSource.setEncoding(encodedResource.getEncoding());
      }
      return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
      }
      catch (IOException ex) {
      throw new BeanDefinitionStoreException(
      "IOException parsing XML document from " + encodedResource.getResource(), ex);
      }
      finally {
      currentResources.remove(encodedResource);
      if (currentResources.isEmpty()) {
      this.resourcesCurrentlyBeingLoaded.remove();
      }
      }
      }

BeanDefinition 阶段

BeanFactory

  • 构建Bean工厂

BeanDefinitionRegistryPostProcessor

  • 获取BeanDefinition
  • 删除BeanDefinition
  • 替换,BeanDefinitionBuilder.build().register.regist() 设置自己的Bean定义/实现类

作为BeanFactoryPostProcessor子类执行优先级更高的原因

  • 都是IOC容器创建调用refresh接口

  • 都调用到invokeBeanFactoryPostProcessors(beanFactory)方法

  • 从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件。

    • 依次触发所有的postProcessBeanDefinitionRegistry()

    • 再触发postProcessBeanFactory()方法BeanFactoryPostProcessor

    • 因此优先于BeanFactoryPostProcessor

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      while (reiterate) {
      reiterate = false;
      postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
      for (String ppName : postProcessorNames) {
      if (!processedBeans.contains(ppName)) {
      currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      processedBeans.add(ppName);
      reiterate = true;
      }
      }
      sortPostProcessors(currentRegistryProcessors, beanFactory);
      registryProcessors.addAll(currentRegistryProcessors);
      //先触发postProcessBeanDefinitionRegistry
      invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
      currentRegistryProcessors.clear();
      }

      // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
      //在此触发postProcessBeanFactory
      invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
      invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
      }
  • 再从容器中找到BeanFactoryPostProcessor组件,然后依次触发postProcessorBeanFactory()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

/**
* 在标准初始化之后,允许用户修改IOC容器Bean Definition Registry
* Modify the application context's internal bean definition registry after its standard initialization.
* 所有合法Bean都将被加载,但是Bean Instance此时还未创建
* 虽是BeanFactoryPostProcessor子类,但优先于BeanFactoryPostProcessor执行
* All regular bean definitions will have been loaded, but no beans will have been instantiated yet.
* This allows for adding further bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

BeanFactoryPostProcessor

  • 对BeanFactory本身的设置(BeanFactory的后置处理器)

  • 在BeanFactory标准初始化之后调用。所有的BeanDefinition已保存加载到BeanFactory中,但Bean Instance仍未创建

  • 时机:IOC容器创建对象 invokeBeanFactoryPostProcessors(beanFactory)

    • org.springframework.context.support.AbstractApplicationContext#refresh
    • org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
    • org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
    • org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(java.util.Collection<? extends org.springframework.beans.factory.config.BeanFactoryPostProcessor>, org.springframework.beans.factory.config.ConfigurableListableBeanFactory)
    • org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory
  • 如何找到所有的BeanFactoryPostProcessor并执行他们的方法

    • 直接在BeanFactory容器中找到所有类型是BeanFactoryPostProcessor的组件,并执行它们的方法
    • 初始化创建其他組件前面执行
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @FunctionalInterface
    public interface BeanFactoryPostProcessor {

    /**
    * 标准初始化之后调用
    * Modify the application context's internal bean factory after its standard initialization.
    * 所有的BeanDefinition已保存加载到BeanFactory中,但Bean Instance仍未创建
    * All bean definitions will have been loaded, but no beans will have been instantiated yet.
    * 允许覆盖或添加属性,甚至是eager-initializing beans
    * This allows for overriding or adding properties even to eager-initializing beans.
    * @param beanFactory the bean factory used by the application context
    * @throws org.springframework.beans.BeansException in case of errors
    */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

    }

MessageSource

  • 执行位置
    • org.springframework.context.support.AbstractApplicationContext#refresh
    • org.springframework.context.support.AbstractApplicationContext#initMessageSource

ApplicationEventMulticaster

  • 事件多播器
  • 执行位置
    • org.springframework.context.support.AbstractApplicationContext#refresh
    • org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster

ApplicationListener

  • 监听容器中发布的事件,完成事件驱动模型的开发
  • 监听ApplicationEvent及其下面的子事件
  • 原理:ContextRefreshedEvent事件
    • 容器创建对象 AbstractApplicationContext #refresh()
    • 容器刷新完成 AbstractApplicationContext #finishRefresh()
    • AbstractApplicationContext #publishEvent(new ContextRefreshedEvent(this))
      • 获取 EventMulticaster : getApplicationEventMulticaster()
      • multicaster派发事件
      • 获取所有的ApplicationListener 根据是否含有Executor判断同步/异步 进行for循环派发
  • 执行位置
    • org.springframework.context.support.AbstractApplicationContext#refresh
    • org.springframework.context.support.AbstractApplicationContext#finishRefresh
    • org.springframework.context.LifecycleProcessor#onRefresh
    • org.springframework.context.support.DefaultLifecycleProcessor#startBeans
    • org.springframework.context.support.DefaultLifecycleProcessor.LifecycleGroup#start
    • org.springframework.context.support.DefaultLifecycleProcessor#doStart
    • org.springframework.context.Lifecycle#start
    • org.springframework.context.support.AbstractApplicationContext#publishEvent(org.springframework.context.ApplicationEvent)
    • org.springframework.context.event.SimpleApplicationEventMulticaster#multicastEvent(org.springframework.context.ApplicationEvent, org.springframework.core.ResolvableType)
    • org.springframework.context.event.SimpleApplicationEventMulticaster#invokeListener
    • org.springframework.context.event.SimpleApplicationEventMulticaster#doInvokeListener
    • org.springframework.context.ApplicationListener#onApplicationEvent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

/**
* 当容器中发布此事件之后,方法触发
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);


/**
* Create a new {@code ApplicationListener} for the given payload consumer.
* @param consumer the event payload consumer
* @param <T> the type of the event payload
* @return a corresponding {@code ApplicationListener} instance
* @since 5.3
* @see PayloadApplicationEvent
*/
static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return event -> consumer.accept(event.getPayload());
}

}

Instantation

Populate && Initialization

Aware

InvokeAware调用部分

  • BeanNameAware
  • BeanClassLoaderAware
  • BeanFactoryAware

IOC完整生命周期

  • BeanNameAware

  • BeanClassLoaderAware

  • BeanFactoryAware

  • EnvironmentAware

  • EmbeddedValueResolverAware

  • ResourceLoaderAware

  • ApplicationEventPublisherAware

  • MessageSourceAware

  • ApplicationContextAware

  • ApplicationStartupAware

  • ServletContextAware

  • LoadTimeWeaverAware

  • ImportAware

BeanPostProcessor

  • Bean后置处理器,Bean对象创建初始化前后进行拦截工作的

  • 解析自定义注解

  • Spring对BeanPostProcessor使用

    • Bean赋值
    • 注入其他组件
    • @Autowired
    • 生命周期注解功能
    • @Async
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public interface BeanPostProcessor {

    //在初始化之前工作
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    return bean;
    }

    //在初始化之后工作
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
    }
    }

Populate-Aware-PostProcessor调用步骤

  • org.springframework.context.support.AbstractApplicationContext#refresh

  • org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization

  • org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons

  • org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)

  • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

  • org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)

    —>

    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

    1
    2
    3
    4
    5
    6
    try {
    //填充属性 autowireByName autowireByType
    populateBean(beanName, mbd, instanceWrapper);
    //初始化Bean
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    invokeAwareMethods(beanName, bean);
    return null;
    }, getAccessControlContext());
    }
    else {
    //调用BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
    invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
    //初始化前
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
    //InitializingBean.afterPropertiesSet()
    invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null),
    beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
    //初始化后
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
    }

Created

Destroy

ApplicationContext

其他 Bean 和进行其他的的上下文初始化

实例化剩余的 Bean 单例

ApplicationContextAware

  • 存储全局ApplicationContext

BeanFactoryAware

来源

https://www.bilibili.com/video/BV1oW41167AV

https://blog.csdn.net/aimeimeiTS/article/details/100135486

Spring ApplicationContext

ApplicationContext 是一个BeanFactory,但额外实现一些功能

  • ApplicationContext管理Bean能力是由什么支持的

    使用DefaultListableBeanFactory实现ApplicationContext管理能力

  • DefaultListableBeanFactory具有什么能力

    各种Post处理

    DefaultListableBeanFactory实现各种BeanDefinitionRegistry

阅读全文 »

JavaWeb过滤器

过滤器 拦截器 区别

过滤器基于JavaWeb

  • filter-serverlet-intercepter-controller

拦截器基于Intercepter

如何注册

web.xml

@WebFilter

FilterRegisterBean+Filter

  • 注册
  • ServletContext Initializer
  • Filter definition
  • addRegister

设计模式

  • 责任链
    • FilterChain
    • FilterConfig

  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor
  • BeanPostProcessor
  • InitializingBean
  • ApplicationContextAware
  • ApplicationListener
阅读全文 »

Springboot自定义注解

BeanPostProcessor的应用案例

  • 使用@interface定义注解
  • 使用BeanPostProcessor处理注解

BeanPostProcessor为bean后置处理器. Spring启动过程中,所有的bean初始化的时候会调用bean的后置处理器.

自定义注解类

1
2
3
4
5
6
7
8
9
10
import org.springframework.stereotype.Component;
import java.lang.annotation.*;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Test {
String value() default "";
}
阅读全文 »

常规方式

  • 通过构造方法实例化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="test" class="com.learn.Test" />
    <bean id="test1" class="com.learn.Test">
    <constructor-arg name="id" value="1"/>
    </bean>
    </beans>
    1
    2
    3
    4
    5
    6
    7
    8
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class DemoApplication {
    public static void main(String[] args) {
    ClassPathXmlApplicationContext ca=new ClassPathXmlApplicationContext("beans.xml");
    Test testA=(Test)ca.getBean("test");
    }
    }
阅读全文 »

Spring中的BeanDefinition

BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口.BeanDefinition描述一个bean. 包括bean的属性,构造函数参数列表,依赖bean,是否是单例,bean的类名等等

BeanDefinition元信息

属性 (Property) 说明
Class Bean全类名,必须是具体类,不能用抽象类或接口
Name Bean的名称或者ID
scope Bean的作用域 (如: singleton, prototype 等)
Constructor arguments Bean构造器参数(用于依赖注入)
Properties Bean属性设置(用于依赖注入)
Autowiring mode Bean自动绑定模式(如:通过名称byName)
Lazy initialization mode Bean延迟初始化模式(延迟和非延迟)
Initialization method Bean初始化回调方法名称
Destruction method Bean销毁回调方法名称
阅读全文 »

List

LinkedList vs ArrayList

Internal implementation

这两个集合都允许重复的元素并维持元素的插入顺序。

LinkedList使用doubly-linked list LinkedList实现它。 ArrayList使用dynamically resizing array实现它。 这将导致性能上的进一步差异。

Performance

Add operation

如果不需要调整Array的大小,则在ArrayList中添加元素是O(1)操作。 如果调整数组大小,则它变为O(log(n))

在LinkedList中添加元素是O(1)操作,因为它不需要任何导航。

阅读全文 »

什么是微服务架构

微服务架构就是将单体的应用程序分成多个应用程序,这多个应用程序就成为微服务,每个微服务运行在自己的进程中,并使用轻量级的机制通信。这些服务围绕业务能力来划分,并通过自动化部署机制来独立部署。这些服务可以使用不同的编程语言,不同数据库,以保证最低限度的集中式管理。

Spring Cloud 是什么

  • Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
  • Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

什么是Spring Cloud Alibaba?

Spring Cloud Alibaba 套件,阿里开源组件、阿里云商业组件整合进 Spring Cloud 体系当中,同时对 Spring Cloud Gateway、OpenFeign、Ribbon 等等进行集成。
主要功能如下:

  • 服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
  • 分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
  • 服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
  • 消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
  • 分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。

Spring Cloud Alibaba和Spring Cloud 的区别和联系

Spring Cloud Alibaba是Spring Cloud的子项目,Spring Cloud Alibaba符合Spring Cloud标准。
随着Spring Cloud Netflix下的相关组件逐步进入维护模式,进入维护模式的意思就是从目前一直到以后一段时间Spring Cloud Netflix提供的服务和功能就这么多了,不再开发新的组件和功能了。同时Spring Cloud官方也在积极孵化其他替代品,以满足Spring Cloud版本迭代的需求。
Spring Cloud Alibaba生态下的各个组件其实在国内很多公司很早之前就有使用,它们在服务治理方面比Spring Cloud Netflix更加强大,而且比较符合国内互联网公司的业务特性,推荐使用。

阅读全文 »