BeanDefinitionRegistryPostProcessor自定义替换spring中的bean

Posted 好大的月亮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BeanDefinitionRegistryPostProcessor自定义替换spring中的bean相关的知识,希望对你有一定的参考价值。

需求

有些时候产品的研发和业务的开发是分开的,当迭代升级的时候如果业务代码耦合在一些产品代码里。那么在升级的时候就会出现代码冲突,甚至功能冲突。

所以一般业务代码都是和产品代码分开的。但是有些时候业务又需要基于产品的代码进行处理,甚至改写一些产品代码。

简单的场景可能就直接用自己的class代替下就行了。但是当产品代码在项目里被多次调用时。又不能直接改产品代码。这个时候走代理模式是比较合适的。

spring的AOP就是经典的代理模式。一些场景的确可以用aop实现。
这里如果了解spring声明周期的话,其实可以利用BeanDefinitionRegistryPostProcessor去替换bean。

代码demo

DemoA实现了Demo接口,此时业务中已经有demoA大量应用了,此时新建了DemoB继承了DemoA。

目的:所有原先调用DemoA bean的地方现在都调用DemoB的bean

方案:DemoA实现org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor接口,将spring容器中的demoA bean remove,然后将注册demoB替换demoA。

公共接口

package com.fchan.business.utils;
public interface Demo 
    void say();

demoA

package com.fchan.business.utils;

import org.springframework.beans.BeansException;
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.stereotype.Service;


@Service
public class DemoA implements Demo, BeanDefinitionRegistryPostProcessor 


    @Override
    public void say() 
        System.out.println("demoA say hello");
    

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException 

    

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException 

        System.out.println("postProcessBeanDefinitionRegistry");

        //remove原先的bean
        beanDefinitionRegistry.removeBeanDefinition("demoA");

        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(DemoB.class);
        //注册搭配spring
        beanDefinitionRegistry.registerBeanDefinition("demoA", beanDefinitionBuilder.getBeanDefinition());

    

demoB

package com.fchan.business.utils;


import com.fchan.business.security.service.UserService;

import javax.annotation.Resource;

public class DemoB extends DemoA 

    @Resource
    private UserService service;



    @Override
    public void say() 
	    System.out.println(this);
        System.out.println("demoB say hello");
        System.out.println(service);
    



测试结果

以上是关于BeanDefinitionRegistryPostProcessor自定义替换spring中的bean的主要内容,如果未能解决你的问题,请参考以下文章