当前位置: 首页 > news >正文

高清品牌网站设计建设汽车网站建设公司哪家好

高清品牌网站设计建设,汽车网站建设公司哪家好,无忧网站建设报价,网站后端技术有哪些前言 前几篇已经介绍lBeanFactory的创建已经xml配置文件中自定义标签和默认标签的解析过程,此时的BeanFactory中已经包含了xml文件中的标签属性。但BeanFactory中还有一些本身重要的属性没有填充,所以接着方法继续往下看BeanFactory中的属性是如何填充的…

前言

前几篇已经介绍lBeanFactory的创建已经xml配置文件中自定义标签和默认标签的解析过程,此时的BeanFactory中已经包含了xml文件中的标签属性。但BeanFactory中还有一些本身重要的属性没有填充,所以接着方法继续往下看BeanFactory中的属性是如何填充的。

refresh
refresh()主流程中前几个方法已经介绍过,这里不过多赘述,去掉后面的无用代码,我们这篇帖子主要看prepareBeanFactory方法中做了些什么。

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing./*** 前戏,做容器刷新前的准备工作* 1、设置容器的启动时间* 2、设置活跃状态为true* 3、设置关闭状态为false* 4、获取Environment对象,并加载当前系统的属性值到Environment对象中* 5、准备监听器和事件的集合对象,默认为空的集合*/prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 创建容器对象:DefaultListableBeanFactory// 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinitionConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// beanFactory的准备工作,对各种属性进行填充prepareBeanFactory(beanFactory);}}

prepareBeanFactory
见名知意,这个方法中也是为了BeanFactory做准备工作,所以刚上来设置了BeanFacroty的类加载器。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.// 设置beanFactory的classloader为当前context的classloaderbeanFactory.setBeanClassLoader(getClassLoader());// 设置beanfactory的表达式语言处理器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具类beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 添加beanPostProcessor,ApplicationContextAwareProcessor此类用来完成某些Aware对象的注入beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 设置要忽略自动装配的接口,这些接口的实现是由容器通过set方法进行注入的,// 所以在使用autowire进行注入的时候需要将这些接口进行忽略beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.// 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.// 注册BPPbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.// 增加对AspectJ的支持,在java中织入分为三种方式,分为编译器织入,类加载器织入,运行期织入,编译器织入是指在java编译器,采用特殊的编译器,将切面织入到java类中,// 而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面,运行期织入则是采用cglib和jdk进行切面的织入// aspectj提供了两种织入方式,第一种是通过特殊编译器,在编译器,将aspectj语言编写的切面类织入到java类中,第二种是类加载期织入,就是下面的load time weaving,此处后续讲if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.// 注册默认的系统环境bean到一级缓存中if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}

StandardBeanExpressionResolver

这个方法主要是创建了一个标准的Bean表达式的解析器。主要是用来对spel表达式的解析。
其中类之间的关系是Resolver处理类 包含了-> spelParser的解析类 包含了 -> spelConfiguration配置类。其中具体的解析过程是在SpelExpressionParser中的doParseExpression()方法完成。

/*** 默认表达式前缀** Default expression prefix: "#{". */public static final String DEFAULT_EXPRESSION_PREFIX = "#{";/*** 默认表达式后缀** Default expression suffix: "}". */public static final String DEFAULT_EXPRESSION_SUFFIX = "}";private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;public StandardBeanExpressionResolver(@Nullable ClassLoader beanClassLoader) {this.expressionParser = new SpelExpressionParser(new SpelParserConfiguration(null, beanClassLoader));}public SpelParserConfiguration(@Nullable SpelCompilerMode compilerMode, @Nullable ClassLoader compilerClassLoader,boolean autoGrowNullReferences, boolean autoGrowCollections, int maximumAutoGrowSize) {this.compilerMode = (compilerMode != null ? compilerMode : defaultCompilerMode);this.compilerClassLoader = compilerClassLoader;this.autoGrowNullReferences = autoGrowNullReferences;this.autoGrowCollections = autoGrowCollections;this.maximumAutoGrowSize = maximumAutoGrowSize;}

SpelExpressionParser
省略具体解析过程。知道使用时会调用doParseExpression方法即可。

public SpelExpressionParser(SpelParserConfiguration configuration) {Assert.notNull(configuration, "SpelParserConfiguration must not be null");this.configuration = configuration;}@Overrideprotected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {return new InternalSpelExpressionParser(this.configuration).doParseExpression(expressionString, context);}

回到prepareBeanFactory主方法,看下面的具体方法。

addPropertyEditorRegistrar

这个方法主要是对类属性的一个扩展,比如说Customer类中引用了Address变量。Address中包含了省市区的属性,但Customer中对address的值是省_市_区,将值捏合成了一个,这时可通过自定义的扩展对类中属性进行拆分。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.// 设置beanFactory的classloader为当前context的classloaderbeanFactory.setBeanClassLoader(getClassLoader());// 设置beanfactory的表达式语言处理器beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));// 为beanFactory增加一个默认的propertyEditor,这个主要是对bean的属性等设置管理的一个工具类beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));}

先看方法的具体执行流程。

ResourceEditorRegistrar
addPropertyEditorRegistrar()方法会为BeanFacroty中PropertyEditorRegistrar属性赋值,在PropertyEditorRegistrar的构造器中,会对类中属性进行初始化赋值,并在类中包含了一个registerCustomEditors()方法。
registerCustomEditors方法会将Spring中默认的一些类注册到Editors中,默认的会执行overrideDefaultEditor操作。
registerCustomEditors方法会在Spring后面的源码中进行调用,这里不过多讲解

public class ResourceEditorRegistrar implements PropertyEditorRegistrar {public ResourceEditorRegistrar(ResourceLoader resourceLoader, PropertyResolver propertyResolver) {this.resourceLoader = resourceLoader;this.propertyResolver = propertyResolver;}@Overridepublic void registerCustomEditors(PropertyEditorRegistry registry) {ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);doRegisterEditor(registry, Resource.class, baseEditor);//省略部分doRegisterEditor代码...if (this.resourceLoader instanceof ResourcePatternResolver) {doRegisterEditor(registry, Resource[].class,new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));}}private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {if (registry instanceof PropertyEditorRegistrySupport) {((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);}else {registry.registerCustomEditor(requiredType, editor);}}
}

ResourceEditor
ResourceEditor类继承了PropertyEditorSupport,PropertyEditorSupport实现了PropertyEditor类,其中ResourceEditor类包含了一些对类属性的一些实现。包括setAsText,setValue等一些方法。

public class ResourceEditor extends PropertyEditorSupport {public void setAsText(String text) throws java.lang.IllegalArgumentException {if (value instanceof String) {setValue(text);return;}throw new java.lang.IllegalArgumentException(text);}public void setValue(Object value) {this.value = value;firePropertyChange();}
}

结合ResourceEditor和ResourceEditorRegistrar两者来看的话,对属性的扩展就是将具体的class类,通过Editor定义好具体的逻辑后,通过Spring框架的识别,而后根据自己定义的逻辑来针对具体的class类的属性进行处理。

自定义类属性扩展

根据上面介绍的执行流程,仿照Spring框架的写法:

  1. 需要类实现PropertyEditorRegistrar类并实现自己的registerCustomEditors方法将类注册到Editors类中
  2. 在自定义的Editors类中,重写setAsText方法,实现类中的属性自定义扩展。
  3. 让自定义的Registrar类能够被Spring发现,并调用。

自定义类
Customer类中包含着Address属性,此时Customer对address的属性设置是“”省_市_区“”的格式,到Address类中要拆分成对应的值。

public class Customer {private String name;private Address address;
}public class Address {private String province;private String city;private String town;
}

实现Registrar
实现Registrar,调实现registerCustomEditors注册。

public class AddressPropertyEditorRegistrar implements PropertyEditorRegistrar {@Overridepublic void registerCustomEditors(PropertyEditorRegistry registry) {registry.registerCustomEditor(Address.class,new AddressPropertyEditor());}
}
//根据参数text属性实现自定义扩展
public class AddressPropertyEditor  extends PropertyEditorSupport {@Overridepublic void setAsText(String text) throws IllegalArgumentException {String[] s = text.split("_");Address address = new Address();address.setProvince(s[0]);address.setCity(s[1]);address.setTown(s[2]);this.setValue(address);}
}

xml配置
这里的xml采用了两种方法配置,目的是让Spring框架可以发现我们自定义的Editor,并进行调用。将我们自定义的Editor填充到CustomEditorConfigurer类中的customEditors属性其实就可让Spring框架发现并调用。这里埋个小坑,会在后面源码具体执行调用customEditors属性时再填。

 <bean id="customer" class="com.xxx.selfEditor.Customer"><property name="name" value="zhangsan"></property><property name="address" value="省_市_区"></property></bean>
<!--    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">-->
<!--        <property name="propertyEditorRegistrars">-->
<!--            <list>-->
<!--                <bean class="com.xxx.selfEditor.AddressPropertyEditorRegistrar"></bean>-->
<!--            </list>-->
<!--        </property>-->
<!--    </bean>--><bean class="org.springframework.beans.factory.config.CustomEditorConfigurer"><property name="customEditors"><map><entry key="com.xxx.selfEditor.Address"><value>com.xxx.selfEditor.AddressPropertyEditor</value></entry></map></property></bean>

ignoreDependencyInterface

忽略自动装配的接口,这些接口的实现是由容器通过set方法进行注入的,所以在使用autowire进行注入的时候需要将这些接口进行忽略。
源码中忽略类的方法有两个,代表着不同的含义,具体可以看这篇帖子,关于ignoreDependencyInterface的方法讲述的很细。

/*** 自动装配时忽略的类** Ignore the given dependency type for autowiring:* for example, String. Default is none.* @param type the dependency type to ignore*/void ignoreDependencyType(Class<?> type);/*** 自动装配时忽略的接口** Ignore the given dependency interface for autowiring.* <p>This will typically be used by application contexts to register* dependencies that are resolved in other ways, like BeanFactory through* BeanFactoryAware or ApplicationContext through ApplicationContextAware.* <p>By default, only the BeanFactoryAware interface is ignored.* For further types to ignore, invoke this method for each type.* @param ifc the dependency interface to ignore* @see org.springframework.beans.factory.BeanFactoryAware* see org.springframework.context.ApplicationContextAware*/void ignoreDependencyInterface(Class<?> ifc);
http://www.yayakq.cn/news/577336/

相关文章:

  • 网站怎么没有排名买源码做网站简单嘛
  • 化州市住房和城乡建设局网站南京好的网站设计公司
  • 应用网站模板个人网页制作程序
  • 免费产品网站建设网站每年要多少钱
  • 网站制作公司价格做跨境电商的网站
  • 茂名市建设银行网站一建工程类专业对照表
  • 国外外贸网站有哪些南充高端网站建设
  • 网站开发的工作方法全国最有实力的信息网络公司排名
  • 最好建设网站西安公司注册核名
  • asp.net网站开发实例视频教程网站流量如何来
  • 北京做网站便宜的公司哪家好西安公司网站制作价格
  • app网站制作wordpress加载中
  • 苏州外贸网站建设运营网站开发策略都有啥
  • 征婚网站 女 做茶叶生意商务网站的特点
  • 做外贸必须有网站吗北京网站建设制作
  • 创建一个网站网站空间费用注销网站和取消接入
  • 专业网站策划公司河北省老区建设促进会网站
  • 网站开发流程有哪几个阶段昆明建设网站哪家好
  • 备案网站域名被抢注wordpress用户组
  • 网站建设教程aspWordPress外链转内链插件
  • 国内做的好看的网站设计手机网站解析地址
  • 如何把自己的网站推广打开wordpress很慢
  • 长沙网站建设推广服务光辉国际猎头公司
  • 网站广告赚钱吗公司招聘要求
  • 有没有哪个做美食的网站漳州网站建设喊博大科技
  • 学习网站建设深圳快速网站制作哪家公司好
  • wordpress网站制作app唐山网站
  • 龙之向导免费网站wordpress首页添加登陆
  • 个人网站备案备注北京工程交易中心官网
  • 建设网站模板星月教你做网站回顾文档