Spring之容器后处理器(内置)

Spring预定义了很多容器后处理器,这里来看如下两个:

CustomEditorConfigurer 用来注册自定义的属性编辑器。

PropertyPlaceholderConfigurer 用来读取属性文件,同时内置了常用的属性编辑器。

实际练习:

通过容器后处理器,装配birthday、sex的转换和装配。

info.properties

username=tom
sex=true

Spring.xml

<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

        <!--ver1-->
        <!--最开始的方法:springBean中注入address-->
        <!--<bean id="address" class="ioc24.Address">
            <property name="city" value="nanjing"/>
            <property name="province" value="jiangsu"/>
        </bean>
        <bean id="springBean" class="ioc24.SpringBean">
            <property name="address" ref="address"/>
        </bean>-->

        <!--BeanFactoryPostProcessor-->
        <bean id="springBean" class="ioc24.SpringBean">
            <property name="address" value="[临沂-山东]"/>
            <property name="birthday" value="1990-12-26"/>
            <property name="username" value="${username}"/>
            <property name="sex" value="${sex}"/>
        </bean>

        <!--ver2-->
        <!--将SpringBeanFacotoryPostProcessor添加到IoC容器中-->
        <!--<bean class="ioc24.SpringBeanFacotoryPostProcessor">
            <property name="cunstomEditors">
                <map>
                    <entry key="ioc24.Address" value="ioc24.editor.AddressEditor"/>
                    <entry key="java.util.Date" value="ioc24.editor.DateEditor"/>
                    <entry key="java.lang.String" value="ioc24.editor.StringEditor"/>
                    <entry key="java.lang.Boolean" value="ioc24.editor.BooleanEditor"/>
                </map>
            </property>
        </bean>-->
        <!--ver3-->
        <!--使用spring提供的CustomEditorConfigurer-->
        <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
            <!--注册属性编辑器-->
            <property name="customEditors">
                <map>
                    <entry key="ioc24.Address" value="ioc24.editor.AddressEditor"/>
                    <entry key="java.util.Date" value="ioc24.editor.DateEditor"/>
                    <!--这两个属性编辑器是我们自定义的,交给-->
                    <!--<entry key="java.lang.String" value="ioc24.editor.StringEditor"/>
                    <entry key="java.lang.Boolean" value="ioc24.editor.BooleanEditor"/>-->
                </map>
            </property>
        </bean>
        <!--使用spring提供的PropertyPlaceholderConfigurer-->
        <!--内置了String Boolean等常用属性编辑器,字符串匹配、格式查找等内部都有实现-->
        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
            <!--该配置后,会自动读取属性文件-->
            <property name="location" value="classpath:ioc24/info.properties"/>
        </bean>
</beans>
package ioc24;

public class Address {
    private String city;
    private String province;

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    @Override
    public String toString() {
        return "Address{" +
                "city='" + city + '\'' +
                ", province='" + province + '\'' +
                '}';
    }
}
package ioc24;

import java.util.Date;

public class SpringBean {
    {
        System.out.println("代码块");
    }
    private Address address;
    private Date birthday;
    private String username;
    private Boolean sex;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Boolean getSex() {
        return sex;
    }

    public void setSex(Boolean sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "SpringBean{" +
                "address=" + address +
                ", birthday=" + birthday +
                ", username='" + username + '\'' +
                ", sex=" + sex +
                '}';
    }
}
package ioc24.editor;

import ioc24.Address;

import java.beans.PropertyEditor;
import java.beans.PropertyEditorSupport;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
* 定义的属性编辑器
*/
//父类中方法较多,这里只需要重写getAsText   setAsText
public class AddressEditor extends PropertyEditorSupport {
    //用来将Address转换为String
    @Override
    public String getAsText() {
        return super.getAsText();
    }

    //将String转换为Address
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        Pattern pattern = Pattern.compile("\\[(.*)-(.*)\\]");
        Matcher matcher = pattern.matcher(text);
        if (matcher.matches()){
            String city = matcher.group(1);
            String provience = matcher.group(2);
            Address address = new Address();
            address.setCity(city);
            address.setProvince(provience);
            //调用setValue设置值
            //说白了就是把修改属性之后的对象,交给容器
            setValue(address);
        }
    }
}
package ioc24.editor;

import ioc24.Util.PropertiesUtils;

import java.beans.PropertyEditorSupport;

public class BooleanEditor extends PropertyEditorSupport {
    @Override
    public String getAsText() {
        return super.getAsText();
    }

    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if(PropertiesUtils.matcher(text)){
            String key = PropertiesUtils.getKey(text);
            PropertiesUtils.load(StringEditor.class.getClassLoader().getResourceAsStream("ioc24/info.properties"));
            //将字符串编程boolean
            boolean b = Boolean.parseBoolean(PropertiesUtils.get(key).toString());
            setValue(b);
        }
    }
}
package ioc24.editor;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateEditor extends PropertyEditorSupport {
    //把日期对象变为文本
    @Override
    public String getAsText() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //把日期对象换成字符串
        return simpleDateFormat.format((Date)getValue());
    }

    //将文本变为日期对象
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            //得到日期对象
            Date parse = simpleDateFormat.parse(text);
            setValue(parse);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}
package ioc24.editor;

import ioc24.Util.PropertiesUtils;

import java.beans.PropertyEditorSupport;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringEditor extends PropertyEditorSupport {
    @Override
    public String getAsText() {
        return super.getAsText();
    }

    //将spring.xml中的${username}变为属性文件中真正的值
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (PropertiesUtils.matcher(text)){
            String key = PropertiesUtils.getKey(text);
            PropertiesUtils.load(StringEditor.class.getClassLoader().getResourceAsStream("ioc24/info.properties"));
            String  value = PropertiesUtils.get(key).toString();
            setValue(value);
        }

    }
}
package ioc24.Util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
* 读取properties文件的工具类
*/
public class PropertiesUtils {
    private static Properties properties;
    //读取属性文件
    public static void load(InputStream inputStream) {
        if (properties == null){
            properties = new Properties();
        }
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取属性值
    public static Object get(String key){
        if (properties.containsKey(key)){
            return properties.get(key);
        }else {
            throw new RuntimeException("在properties文件中找不到值,key:"+key);
        }
    }

    //判断是否符合格式
    public static boolean matcher(String string){
        Pattern pattern = Pattern.compile("\\$\\{(.*)\\}");
        Matcher matcher = pattern.matcher(string);
        return matcher.matches();
    }


    //处理字符串
    public static String getKey(String string){
        Pattern pattern = Pattern.compile("\\$\\{(.*)\\}");
        Matcher matcher = pattern.matcher(string);
        if(matcher.matches()){
            return matcher.group(1);
        }else {
            throw new RuntimeException("格式不正确,string:"+string);
        }
    }

}
package ioc24;

import ioc24.editor.AddressEditor;
import ioc24.editor.DateEditor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import java.beans.PropertyEditor;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

/**
 *定义容器后处理器
 * 作用:通过注册属性编辑器,完成属性的转换和装配
 *
 */

public class SpringBeanFacotoryPostProcessor implements BeanFactoryPostProcessor {
    //cunstomEditors中存放的属性编辑器是ioc容器根据spring.xml自动注入的
    private Map<Class,Class<? extends PropertyEditor>> cunstomEditors;
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("SpringBeanFacotoryPostProcessor.postProcessBeanFactory");
        //向容器中注册属性编辑器
        //第1个参数:要转换的属性类型   第2个参数:要使用的属性编辑器类型
        //该属性编辑器在装配的时候,如果遇到Address类型的数据要装配,那就把value值经过AddressEditor进行转换,将String转换成Address类型,完成装配
        /*beanFactory.registerCustomEditor(Address.class, AddressEditor.class);
        beanFactory.registerCustomEditor(Date.class, DateEditor.class);*/

        //上边每注册一个容器后处理器都要一个那一行代码,麻烦
        //这里优化
        //cunstomEditors.entrySet()  遍历键值对(Entry<key,value>)
        for (Entry<Class,Class<? extends PropertyEditor>> entry : cunstomEditors.entrySet()){
            beanFactory.registerCustomEditor(entry.getKey(),entry.getValue());
        }
    }

    public Map<Class, Class<? extends PropertyEditor>> getCunstomEditors() {
        return cunstomEditors;
    }

    public void setCunstomEditors(Map<Class, Class<? extends PropertyEditor>> cunstomEditors) {
        this.cunstomEditors = cunstomEditors;
    }
}
package ioc24;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String [] args){
        ApplicationContext ac = new ClassPathXmlApplicationContext("ioc24/spring.xml");
        System.out.println(ac.getBean("springBean"));
    }
}

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值