spring xml中的String值是怎么转化成我们所需要类型的

在Spring的配置中,使用配置类还稍微好理解一点,毕竟直接使用的就是相对应的对象,但是使用XML时就稍稍有点难理解,在XML解析时里面的像这样的子元素

<property name="" value=""/>

value值统统都会转化成String值,我们有时候对应的property对应的类型是int将其转换成int也就罢了,但有时候不是int,而是像Date,Resource,File等等这些类型,他又是怎么转化过去的呢?

比如:

import org.springframework.core.io.Resource;

public class Test {
    Resource resource;
    public Test(Resource resource){
        this.resource=resource;
    }
}

这里边有个Resource属性

<bean id="test" class="Helison.Test">
    <constructor-arg index="0" value="classpath:resources"/>
 </bean>

在XML文件里面将会这么配置,运行完全成功,不报错,为什么呢,value明明是String啊,此时将涉及到PropertyEditor(属性编辑器)以及相关的类了

spring在为bean的相关属性进行赋值的时候,会在其beanFactory里面寻找相对应的属性编辑器,其作用是将解析到的String类型的值转化成我们所需要的其他类型的值,比如Resource,Date等等,因此你需要提供一种映射机制去做这件事;

相关Spring的源码如下:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	//关键是这句话
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   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.
   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.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   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.
   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());
   }
}

ResourceEditorRegistrar相关源码:

注册相关的PropertyEditor

public void registerCustomEditors(PropertyEditorRegistry registry) {
    ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
    this.doRegisterEditor(registry, Resource.class, baseEditor);
    this.doRegisterEditor(registry, ContextResource.class, baseEditor);
    this.doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
    this.doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
    this.doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
    if (pathClass != null) {
        this.doRegisterEditor(registry, pathClass, new PathEditor(baseEditor));
    }

    this.doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
    this.doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
    ClassLoader classLoader = this.resourceLoader.getClassLoader();
    this.doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
    this.doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
    this.doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
    if (this.resourceLoader instanceof ResourcePatternResolver) {
        this.doRegisterEditor(registry, Resource[].class, new ResourceArrayPropertyEditor((ResourcePatternResolver)this.resourceLoader, this.propertyResolver));
    }

}

上面源码注册已经为我们注册了一些常用的PropertyEditor,像Resource,File,Url等等,but,我们自己注册的那些在哪呢???

继续探索源码,发现:

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
    Object result = existingBean;
    Iterator var4 = this.getBeanPostProcessors().iterator();

    do {
        if (!var4.hasNext()) {
            return result;
        }

        BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
        result = beanProcessor.postProcessBeforeInitialization(result, beanName);
    } while(result != null);

    return result;
}

在进行为beanFactory进行配置后会调用上述方法,而

public class CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered 

CustomEditorConfigurer实现了BeanFactoryPostProcessor(注,BeanFactoryPostProcessor是个很重要的接口)将会被容器发现,并注册

因此我们只需要在配置文件中声明一个CustomEditorConfigurer,就好了,如下:

<bean  class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="propertyEditorRegistrars">
        <list>
            <bean class="Helison.DatePropertyEditor"/>
        </list>
    </property>
</bean>

public class DatePropertyEditor implements PropertyEditorRegistrar {
    @Override
    public void registerCustomEditors(PropertyEditorRegistry propertyEditorRegistry) {
        propertyEditorRegistry.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true));
    }
}

此时就可以放心的进行使用了

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码实现? 感谢您的提问。在Spring XML配置JavaMail可以通过以下步骤实现: 1. 首先,您需要Spring配置文件添加以下依赖项: ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4.7</version> </dependency> ``` 2. 接下来,您需要创建一个JavaMailSenderImpl Bean,如下所示: ``` <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"> <property name="host" value="smtp.gmail.com"/> <property name="port" value="587"/> <property name="username" value="your_email_address"/> <property name="password" value="your_email_password"/> <property name="javaMailProperties"> <props> <prop key="mail.smtp.auth">true</prop> <prop key="mail.smtp.starttls.enable">true</prop> </props> </property> </bean> ``` 请注意,上面的示例是使用Gmail的SMTP服务器而不是您的邮箱服务器配置。您需要将其更改为适合您的需求的主机名、端口、用户名和密码。 3. 最后,您可以在Spring Bean注入JavaMailSenderImpl,并使用以下Java代码发送电子邮件: ``` @Autowired private JavaMailSender mailSender; public void sendEmail(String recipient, String subject, String message) { SimpleMailMessage mail = new SimpleMailMessage(); mail.setTo(recipient); mail.setSubject(subject); mail.setText(message); mailSender.send(mail); } ``` 以上就是在Spring XML配置JavaMail的过程。希望这能帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值