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);
    }


}

测试结果

在这里插入图片描述


版权声明:本文为weixin_43944305原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。