当前位置: 首页>编程语言>正文

Spring Authorization Server刷新token spring刷新某个bean

1、容器技术内幕-AbstractApplicationContext.Refresh()

     AbstractApplicationContext : 是ApplicationContext的抽象类,里面的refresh()方法是容器加载的入口。
     Refresh()方法的主要流程如下:   
      第1步:初始化BeanFactory。
                  ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()

第2步:调用工厂后置处理器,之前生命周期中的BeanFactoryPostProcessor。     
                  invokeBeanFactoryPostProcessors()

第3步:注册BeanPostProcessor,之前生命周期中的BeanPostProcessor在ApplicationContext加载的时候,在此处统一注册到                    BeanFactory中。
                  registerBeanPostProcessors();

第4步:初始化消息源。
                  initMessageSource();

  第5步:初始化应用上下文事件广播器。
                  initApplicationEventMulticaster();

第6步:初始化其他特殊的bean,由具体的子类实现。
                  onRefresh();

第7步:注册事件监听器。
                   registerListeners();

      第8步:初始化所有单实例bean,延迟加载的除外,所有的bean都在此步骤实例化、属性设置包含依赖注入、初始化。
                   finishBeanFactoryInitialzation(beanFactory);

第9步:完成容器刷新,并广播容器刷新事件。
                   finishRefresh();

2主要组件

 2.1BeanDefinition:用于描述一个java类

             org.springframework.beans.factory.config.BeanDefinition, 主要就是定义bean的一些属性,此类结构图如下:

                     

Spring Authorization Server刷新token spring刷新某个bean,Spring Authorization Server刷新token spring刷新某个bean_java,第1张

 

Spring 通过BeanDefinitionReader读取配置信息的Resource,将其转化为容器的内部表示BeanDefinition,并且将这些                  BeanDefinition注册到BeanDefinitionRegistry中,BeanDefinitionRegistry就像是spring配置信息的内存数据库,后续操                作将直接从BeanDefinitionRegistry中读取配置信息。

 

   2.2BeanDefinition加载流程

               分为以下两步:

1、通过BeanDefinitionReader读取配置信息的Resource,通过解析,生成BeanDefinition,此处的BeanDefinition                                可能是个半成品,因为在bean的定义中,可能存在占位符变量应用外部属性文件中配置的属性,如${jdbc.url}等                                变量引用,这些变量在此处还没有被解析出来,因此此时的BeanDefinition可能是一个半成品。

2、利用BeanFactoryPostProcessor对半成品的BeanDefinition进行加工处理,将使用占位符应用的配置解析为最                                 终的实际值,这样这些半成品的BeanDefinition就被加工成为成品了。

        2.3、PropertyPlaceholderConfigurer项目配置载入

                PropertyPlaceholderConfigurer, 此类能够将bean 配置的引用外部属性文件中的参数解析为实际值,                                              PropertyPlaceholderConfigurer此类也是实现了BeanFactoryPostProcessor接口,因而也是一个工厂后置处理器。像                    ${jdbc.url}就是使用此工厂后置处理器解析为外部属性文件中的实际值的。
                使用PropertyPlaceholderConfigurer:
                        1、直接定义<bean>:             
                 

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
                                         p:locations="classpath:application.properties,classpath:tapp.properties"
                                         p:fileEncoding="utf-8"
                                         p:placeholderPrefix="${"
                                         p:placeholderSuffix="}"
                                         p:order="1"/>

2、使用context命名空间简化上述配置如下:默认使用${变量名}

<context:property-placeholder ignore-unresolvable="true"
                                            location="classpath:application.properties"
                                            file-encoding="utf-8"
                                            order="1" />

                       属性引用方式:
                                Xml 中获取配置方式:  <property name="maxIdle" value="${redis.maxIdle}"/>

                                注解中获取配置方式:

@Component()
                                           public class Car {@Value("${jdbcRrl}")
                                                 private String jdbcurl;
                                           }

2.4<util:properties/> util命名空间项目配置载入

               配置方式:

<util:properties id="meta" location="classpath:config/metainfo.properties" />

               属性引用方式:
                      Xml 中获取配置方式:  <property name="maxIdle" value="#{meta['redis.maxIdle']}"/>

               注解中获取配置方式:

@Component()
                      public class Car {@Value("#{meta['redis.maxIdle']}")
                           private String jdbcurl;
                      }

2.5、属性文件自身引用

            如下:比如在application.properties文件中
                       dbName=aaa
                       dbUrl=jdbc:mysql://localhost:3306/${dbname}  此处就是属性文件中自身引用,参数名称字符中不能引用!!!

            使用小技巧:如果一个属性值太长,可以使用“\”将属性划分为多行如:
                                 desc : aaa\
                                            bbb\
                                            ccc
                                 就等价于desc=aaabbbccc

             引用bean的属性值:
                        xml 中引用格式: 使用#{beanName.属性名称} 来取值。

<bean id="boss" class="com.wzy.springstudy.propertyEditor.Boss" p:name="马云" />
                                     <bean id="boss1" class="com.wzy.springstudy.propertyEditor.Boss" p:name="#{boss.name}"/>

                       注解中引用格式:@Value("#{beanName.name}")。

@Component
                                     public class Car {                                            @Value("#{boss.name}")
                                             private String name;
                                     }

2.6、InstantiationStrategy:  bean的实例化策略

              org.springframework.beans.factory.support.InstantiationStrategy 主要负责根据BeanDefinition对象创建一个Bean实                例,此接口类图如下:

                                        

Spring Authorization Server刷新token spring刷新某个bean,Spring Authorization Server刷新token spring刷新某个bean_初始化_02,第2张

SimpleInstantiationStrategy

CglibSubclassingInstantiationStrategy 扩展了SimpleInstantiationStrategy ,为需要进行方法注入(如前面提到的                          lookup、replace方法注入)的bean提供支持,它是利用CGLIB类库为bean动态生成子类,在子类中生成方法注入的逻                    辑,然后使用这个动态生成的子类创建bean的实例。

                总结:InstantiationStrategy仅负责bean的实例化工作,相当于执行Java中的new 对象的功能,它并不会参与bean属性                            的设置工作。所以InstantiationStrategy返回的beanshi里实际上只是一个半成品的bean实例,属性填充的工作由                            BeanWrapper来完成。

 

     2.7BeanWrapper:bean包装器

              org.springframework.beans.BeanWrapper ,相当于一个代理器,spring 委托BeanWrapper完成bean的属性填充工作,              在bean被InstantiationStrategy实例化之后,容器主程序将bean实例通过BeanWrapper包装起来,这个包装是通过                        BeanWrapper实现类BeanWrapperImpl的setWrappedInstance方法来完成的。

            BeanWrapper 类图:

Spring Authorization Server刷新token spring刷新某个bean,Spring Authorization Server刷新token spring刷新某个bean_bc_03,第3张

            实现类只有一个就是BeanWrapperImpl, 从类图来看BeanWrapper的实现类

            BeanWrapperImpl有三重身份:

                                             1、Bean包装器。

                                             2、属性访问器。

                                             3、属性编辑器注册表。

            属性填充流程:

从BeanDefinitionRegistry中获取BeanDefinition,然后获取到bean的propertyValue,然后使用PropertyEditor进                            行转换得到bean的属性值。

 

2.8、属性编辑器                  

                      spring的属性编辑器也是使用Java的属性编辑器,我们只需要配置
                   org.springframework.beans.factory.config.CustomEditorConfigurer此配置即可。

 

             1、自定义属性编辑器方式一

                   步骤1:定义自己的属性编辑器,直接继承PropertyEditorSupport 重写setAsText(String text)方法。

                   步骤2:将自定义的属性编辑器配置到spring的CustomEditorConfigurer即可。

                   案例如下:

public class Boss {
                                private String name;
                                private Car car;
                          }


                         public class Car {
                                private String name;
                                private String price;
                         }

                         public class CustomCarEditor extends PropertyEditorSupport {
                               @Override
                               public void setAsText(String text) throws IllegalArgumentException {
                                        String[] strings = text.split(",");
                                        Car car = new Car();
                                        car.setName(strings[0] );
                                        car.setPrice(strings[1]);
                                        //调用父类的setValue()方法设置转换后的属性值。
                                       setValue(car);
                                }
                          }


                         <bean id="boss" class="com.wzy.springstudy.propertyEditor.Boss" p:name="马云" p:car="迈巴赫,1100w"/>

                         <!--用户属性编辑器配置-->
                         <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
                                 <property name="customEditors">
                                       <map>
                                             //Key 表示需要属性编辑的类型,value 表示使用的编辑器。
                                             <entry key="com.wzy.springstudy.propertyEditor.Car"
                                                           value="com.wzy.springstudy.propertyEditor.CustomCarEditor"/>
                                      </map>
                                 </property>
                         </bean>

 

            2、自定义属性编辑器方式二

                      使用JavaBean规范,就是在相同的包路径下面找ClassName+Edior的类,如果找到了就直接使用此属性编辑器,                         无需配置org.springframework.beans.factory.config.CustomEditorConfigurer
                 如:com.wzy.springstudy.propertyEditor.Car
                        com.wzy.springstudy.propertyEditor.CarEditor 就是JavaBean的规范,因此CarEditor 就是Car类型的属性编辑器。
                        在spring中配置依旧如下:

<bean id="boss" class="com.wzy.springstudy.propertyEditor.Boss" p:name="马云" p:car="迈巴                                                                                                                                                                                           赫,1100w"/>

https://www.xamrdz.com/lan/5wj1935576.html

相关文章: