Bootstrap

springIoc 后置处理器之BeanFactoryPostProcessor

BeanFactoryPostProcessor简介:
BeanFactory后处理器,实现BeanFactoryPostProcessor接口,也成为容器后处理器。
容器后处理器在bean创建之前,修改bean的定义属性。

bean的生命周期:

BeanFactoryPostProcessor->代码块->实例化->数据装配->初始化之前->初始化方法->初始化之后->就绪->使用->销毁方法->从容器销毁

实现步骤:

一:定义一个类,实现BeanFactoryPostProcessor

二:将该bean添加到ioc容器中。

三:定义属性编辑器(转换器)实现PropertyEditorJ接口或者实现PropertyEditorSupport;

四:在容器后处理器中注册属性编辑器
先添加jar包

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!--spring-core-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <!--spring-bean-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <!--spring-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <!--spring-expression-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
        </dependency>
    </dependencies>

第二步创建配置文件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">
  
</beans>

第三步书写一个类Address

package com.ioc17.entity;

/**
 * package_name:com.ioc17.entity
 * Author:徐亚远
 * Date:2020/2/16 12:06
 * 项目名:springDemo01
 * Desription:
 **/
public class Address {
    private String province;
    private String city;

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

    public String getProvince() {
        return province;
    }

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

    public String getCity() {
        return city;
    }

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

书写RefAddress类

package com.ioc17.entity;

/**
 * package_name:com.ioc17.entity
 * Author:徐亚远
 * Date:2020/2/16 12:07
 * 项目名:springDemo01
 * Desription:
 **/
public class RefAddress {
    private Address address;
    
    {
        System.out.println("代码块");
    }

    @Override
    public String toString() {
        return "RefAddress{" +
                "address=" + address +
                '}';
    }

    public Address getAddress() {
        return address;
    }

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

定义一个类,实现BeanFactoryPostProcessor

package com.ioc17.entity;

import com.ioc17.editor.AddressEditor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

/**
 * package_name:com.ioc17.entity
 * Author:徐亚远
 * Date:2020/2/16 12:21
 * 项目名:springDemo01
 * Desription:
 **/
public class RefAddressBeanPostProcessor implements BeanFactoryPostProcessor {
    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     *
     * @param beanFactory the bean factory used by the application context
     * @throws BeansException in case of errors
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("hello");
        /**第一个属性是要转换的属性类型,第二个属性是转换器类*/
        beanFactory.registerCustomEditor(Address.class,AddressEditor.class);
    }
}

将bean添加到ioc容器中配置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">

    <bean id="refAddress" class="com.ioc17.entity.RefAddress">
        <property name="address" value="[河南-商丘]"/>
    </bean>
</beans>

定义属性编辑器(转换器)实现PropertyEditorJ接口或者实现PropertyEditorSupport;

package com.ioc17.editor;

import com.ioc17.entity.Address;

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

/**
 * package_name:com.ioc17.editor
 * Author:徐亚远
 * Date:2020/2/18 15:18
 * 项目名:springDemo01
 * Desription:转换器
 **/
public class AddressEditor extends PropertyEditorSupport {
    /**
     * 获取字符串将Address转换成字符串
     */
    @Override
    public String getAsText() {
        Address address = (Address) getValue();
        return "["+address.getProvince()+"-"+address.getCity()+"]";

    }

    /**
     * @param text 将字符串转换成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 province = matcher.group(2);
            Address address = new Address();
            address.setCity(city);
            address.setProvince(province);
            setValue(address);
        }

    }
}

在容器后处理器中注册属性编辑器
<?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">

    <bean id="refAddress" class="com.ioc17.entity.RefAddress">
        <property name="address" value="[河南-商丘]"/>
    </bean>
   <!--在容器后处理器中注册属性编辑器-->
   <bean id="postProcessor" class="com.ioc17.entity.RefAddressBeanPostProcessor"></bean>

</beans>

书写测试类

package com.ioc17.controller;

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

/**
 * package_name:com.ioc17.controller
 * Author:徐亚远
 * Date:2020/2/16 12:08
 * 项目名:springDemo01
 * Desription:
 **/
public class TestRef {
    public static void main(String [] args){
        ApplicationContext ac = new ClassPathXmlApplicationContext("ioc17/spring.xml");
        System.out.println(ac.getBean("refAddress"));
    }
}

测试结果:
在这里插入图片描述

;