likes
comments
collection
share

[每日一问]5.什么是Spring后置处理器及底层原理深度剖析

作者站长头像
站长
· 阅读数 13

昨日回顾

昨天我们聊了 《spring循环依赖及底层原理剖析》。我们了解到spring循环依赖是通过三级缓存和BeanPostProcessor实现,并且了解到spring的循环依赖的一些限制条件( 1.循环依赖只适用于 singleton 作用域的 Bean。对于 prototype 作用域的 Bean,Spring 无法解决循环依赖问题。2.循环依赖只适用于 constructor 和 setter 注入方式。对于其他的注入方式,如字段注入或方法注入,Spring 无法解决循环依赖问题。 ),以及相关的源码分析。

今天我们来着重聊聊BeanPostProcessor。以及源码剖析和场景应用。毕竟要学以致用嘛。

1.基本概念

Spring后置处理器是Spring框架中的一个重要组件,它可以在Bean的初始化过程中对Bean进行一系列的处理,包括对Bean的属性进行赋值、对Bean进行AOP代理、对Bean进行事件监听等。Spring后置处理器是Spring框架中的扩展点,可以通过实现Spring提供的接口来自定义后置处理器,从而实现对Bean的自定义处理。

Spring后置处理器的底层原理主要涉及到Spring框架中的BeanPostProcessor接口以及Spring容器的初始化过程。

  1. 在Spring容器的初始化过程中,当容器加载BeanDefinition时,会将BeanDefinition封装成BeanDefinitionHolder对象,并将其保存到一个ConcurrentHashMap中。当容器初始化完毕后,会根据保存的BeanDefinitionHolder对象创建Bean实例,并将其保存到一个ConcurrentHashMap中。在这个过程中,Spring会依次执行所有注册的BeanPostProcessor实现类的postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法,对Bean进行处理。

  2. 在执行BeanPostProcessor的postProcessBeforeInitialization()方法时,Spring会将Bean实例传递给BeanPostProcessor,并且在方法执行完毕后返回处理后的Bean实例。在执行BeanPostProcessor的postProcessAfterInitialization()方法时,Spring会将处理后的Bean实例传递给BeanPostProcessor,并且在方法执行完毕后返回最终的处理后的Bean实例。

  3. 通过实现BeanPostProcessor接口,我们可以自定义对Bean的处理逻辑。例如,我们可以实现一个BeanPostProcessor来对Bean的属性进行加密处理,或者实现一个BeanPostProcessor来对Bean进行AOP代理等。

Spring后置处理器是Spring框架中的一个重要组件,它可以帮助我们在Bean的初始化过程中对Bean进行一系列的处理,从而实现对Bean的自定义处理。其底层原理主要涉及到Spring框架中的BeanPostProcessor接口以及Spring容器的初始化过程。

2. 使用场景示例

Spring后置处理器可以在Bean的实例化、初始化和销毁等过程中对Bean进行处理,可以实现一些特殊的需求,例如:

  1. 自定义注解处理器:可以通过实现BeanPostProcessor接口,在Bean初始化前后对Bean进行注解解析和处理,实现一些特殊的功能。
  2. AOP切面实现:可以通过实现BeanPostProcessor接口,在Bean初始化前后对Bean进行代理,实现AOP的切面功能。
  3. 实现自定义的依赖注入:可以通过实现BeanPostProcessor接口,在Bean初始化前后对Bean进行依赖注入,实现一些特殊的依赖注入方式。

示例代码:

1. 自定义注解处理器

假设我们有一个自定义注解@MyAnnotation,我们想在初始化标记了该注解的Bean时输出一些信息,可以通过实现BeanPostProcessor接口来实现:

@Component
public class MyAnnotationProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass().isAnnotationPresent(MyAnnotation.class)) {
            System.out.println("Initializing bean: " + beanName);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

在上述代码中,我们在postProcessBeforeInitialization方法中判断了标记了@MyAnnotation注解的Bean,并输出了相关信息。

2. AOP切面实现

假设我们有一个UserService接口和一个UserServiceImpl实现类,我们想在UserService中的所有方法执行前后输出日志,可以通过实现BeanPostProcessor接口来实现:

@Component
public class LoggingAspect implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof UserService) {
            return Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(),
                    (proxy, method, args) -> {
                        System.out.println("Before method: " + method.getName());
                        Object result = method.invoke(bean, args);
                        return result;
                    });
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

我们在postProcessBeforeInitialization方法中判断了是否是UserService接口类型的Bean,并通过动态代理实现了在方法执行前输出日志的功能。

3. 实现自定义的依赖注入

假设我们有一个UserService接口和一个UserServiceImpl实现类,我们想在初始化UserServiceImpl实例时,将UserDao的实现注入进来,可以通过实现BeanPostProcessor接口来实现:

@Component
public class UserDaoInjector implements BeanPostProcessor {

    @Autowired
    private UserDao userDao;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof UserServiceImpl) {
            ((UserServiceImpl) bean).setUserDao(userDao);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

在postProcessBeforeInitialization方法中判断了是否是UserServiceImpl类型的Bean,并将UserDao的实现注入进来。

3. 核心源码剖析

  1. BeanPostProcessor接口
public interface BeanPostProcessor {
    // 在Bean的初始化之前执行,可以修改Bean实例或返回其他Bean实例
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    // 在Bean的初始化之后执行,可以修改Bean实例或返回其他Bean实例
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}
  1. AbstractAutowireCapableBeanFactory
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {
    // 用于保存所有注册的BeanPostProcessor实现类
    private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

    // 用于执行BeanPostProcessor的postProcessBeforeInitialization()方法
    protected Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

    // 用于执行BeanPostProcessor的postProcessAfterInitialization()方法
    protected Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {
        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessAfterInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

    // 注册BeanPostProcessor实现类
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
    }

    // 获取所有注册的BeanPostProcessor实现类
    public List<BeanPostProcessor> getBeanPostProcessors() {
        return this.beanPostProcessors;
    }
}
  1. AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
        implements ConfigurableApplicationContext {
    // 用于执行BeanFactoryPostProcessor的postProcessBeanFactory()方法
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 获取所有注册的BeanFactoryPostProcessor实现类
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<String> beanNames = new ArrayList<>(beanFactory.getBeanDefinitionCount());
        // 首先获取所有实现了PriorityOrdered接口的BeanFactoryPostProcessor实现类
        collectBeanFactoryPostProcessors(beanFactory, priorityOrderedPostProcessors);
        // 对实现了PriorityOrdered接口的BeanFactoryPostProcessor实现类按照指定顺序执行postProcessBeanFactory()方法
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 获取所有实现了BeanFactoryPostProcessor接口的Bean实例
        String[] beanProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        for (String beanProcessorName : beanProcessorNames) {
            if (beanFactory.isTypeMatch(beanProcessorName, PriorityOrdered.class)) {
                continue;
            }
            beanNames.add(beanProcessorName);
        }
        // 对实现了BeanFactoryPostProcessor接口的Bean实例按照指定顺序执行postProcessBeanFactory()方法
        collectBeanFactoryPostProcessors(beanFactory, regularPostProcessors, beanNames);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    // 获取实现了BeanFactoryPostProcessor接口的Bean实例,并按照指定顺序执行postProcessBeanFactory()方法
    private void collectBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,
            List<BeanFactoryPostProcessor> beanFactoryPostProcessors, List<String> beanNames) {
        for (String beanName : beanNames) {
            if (beanFactory.containsBeanDefinition(beanName)) {
                BeanDefinition bd = beanFactory.getMergedBeanDefinition(beanName);
                // 判断Bean实例是否是BeanFactoryPostProcessor实现类
                           
if (BeanFactoryPostProcessor.class.isAssignableFrom(bd.getBeanClass())) {  
Object bean = beanFactory.getBean(beanName);  
beanFactoryPostProcessors.add((BeanFactoryPostProcessor) bean);  
}  
}  
}  
// 对实现了BeanFactoryPostProcessor接口的Bean实例按照指定顺序执行postProcessBeanFactory()方法  
Collections.sort(beanFactoryPostProcessors, OrderComparator.INSTANCE);  
for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessors) {  
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);  
}  
}

// 获取实现了PriorityOrdered接口的BeanFactoryPostProcessor实现类,并按照指定顺序执行postProcessBeanFactory()方法
private void collectBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,
        List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class,
            true, false);
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanFactoryPostProcessor pp = beanFactory.getBean(ppName, BeanFactoryPostProcessor.class);
            beanFactoryPostProcessors.add(pp);
        }
    }
    Collections.sort(beanFactoryPostProcessors, OrderComparator.INSTANCE);
}

// 对指定的BeanFactoryPostProcessor实现类执行postProcessBeanFactory()方法
private void invokeBeanFactoryPostProcessors(List<BeanFactoryPostProcessor> postProcessors,
        ConfigurableListableBeanFactory beanFactory) {
    for (BeanFactoryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanFactory(beanFactory);
    }
}

// 用于执行BeanPostProcessor的postProcessBeforeInitialization()方法
protected Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanFactory().getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

// 用于执行BeanPostProcessor的postProcessAfterInitialization()方法
protected Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanFactory().getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}