Spring的BeanDefinitionRegistryPostProcessor使用

BeanDefinitionRegistryPostProcessor就是用来自定义bean的,并手动注入到Spring的容器里面,有时候觉得定义bean直接使用注解或者xml配置更方便,但是Spring既然提供,肯定是有道理,尝试一下。

这种使用一般是自己用来封装一些扩展插件的时候使用。

BeanDefinitionRegistryPostProcessor 就是一个定义很简单的接口,要想实现实现自定义bean只需要实现这个接口就行。

/**
 * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
 * the registration of further bean definitions <i>before</i> regular
 * BeanFactoryPostProcessor detection kicks in. In particular,
 * BeanDefinitionRegistryPostProcessor may register further bean definitions
 * which in turn define BeanFactoryPostProcessor instances.
 *
 * @author Juergen Hoeller
 * @since 3.0.1
 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

	/**
	 * Modify the application context's internal bean definition registry after its
	 * standard initialization. All regular bean definitions will have been loaded,
	 * but no beans will have been instantiated yet. This allows for adding further
	 * bean definitions before the next post-processing phase kicks in.
	 * @param registry the bean definition registry used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

自定义实现bean定义

package com.madman.annotation.springextension;

import com.madman.annotation.entity.Blue;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * <pre>
 * 【类型】: CustomBeanDefinitionRegistryPostProcessor <br/>
 * 【作用】: 请填写此类的作用<br/>
 * 【时间】:2019/1/3 14:50 <br/>
 * 【作者】:madman <br/>
 * </pre>
 */
@Configuration
@Component
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition("com.madman.annotation.entity.Blue");
        beanDefinitionBuilder.addPropertyValue("name", "小鹏一号");
        beanDefinitionBuilder.addPropertyValue("age", "18");

        BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Blue.class).getBeanDefinition();
        beanDefinition.getPropertyValues().add("name", "小鹏二号");
        beanDefinition.getPropertyValues().add("age", "28");


        registry.registerBeanDefinition("bule_01", beanDefinitionBuilder.getBeanDefinition());
        registry.registerBeanDefinition("bule_02", beanDefinition);

    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

自定义bean最重要的类就是BeanDefinition接口了,这个接口里面定义了注册bean的各种属性,一般我们定义bean的时候都是用的BeanDefinitionBuilder这个spring提供的定义bean的工具类,上面的这个自定义的bean里面也是用的这个来创建bean。
上面的代码使用了两种形式创建了bean,

这种形式是直接通过类名的全路径进行定义的,定义好之后可以addPropertyValue方法来设置属性。
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition("com.madman.annotation.entity.Blue");
beanDefinitionBuilder.addPropertyValue("name", "小鹏一号");
这种形式就是通过Class的形式来定义bean的,这个形式得到的是BeanDefinition对象,所以设置属性的方式和上面不一样。
        BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Blue.class).getBeanDefinition();
beanDefinition.getPropertyValues().add("name", "小鹏二号");
最后注册bean使用的是registry的registerBeanDefinition方法来注册bean,registry属性也有很多方法,是否包含,移除bean等操作,可以用来判断bean是否存在或者名字是否存在等一些操作。
        registry.registerBeanDefinition("bule_02", beanDefinition);

自定义bean之后,就需要使用这类注入到spring容器里面去,这里我直接使用了@Configuration,@Component这两个注解,把这类当成一个组件,扫描的时候直接扫进去就行了。
最后测试的结果是这样的,属性和上面是一一对应的。

public class start_1 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotation = new AnnotationConfigApplicationContext(Config_1.class);
        Map<String, Blue> beansOfType = annotation.getBeansOfType(Blue.class);
        for (String s : beansOfType.keySet()) {
            System.out.println("名字是:" + s);
            System.out.println(beansOfType.get(s).toString());
        }
    }
}
无参数构造函数
无参数构造函数
无参数构造函数
名字是:blue
Blue{name='19', age=12}
名字是:bule_01
Blue{name='小鹏一号', age=18}
名字是:bule_02
Blue{name='小鹏二号', age=28}

猜你喜欢

转载自blog.csdn.net/u010316188/article/details/85699989
今日推荐