Spring Framework-Post Processor(后置处理器)

Spring容器给用户提供了三种Post Processor

  • 容器级别

  • BeanDefinitionRegistryPostProcessor

  • BeanFactoryPostProcessor

  • Bean级别

  • BeanPostProcessor

  • 执行顺序

BeanDefinitionRegistryPostProcessor -> BeanFactoryPostProcessor -> BeanPostProcessor

  1. BeanDefinitionRegistryPostProcessor

用来给容器注册额外的BeanDefinition。

  • 实际案例

“Spring注解容器”通过BeanDefinitionRegistryPostProcessor给容器注册ConfigurationClassPostProcessor来处理 @Configuration标签。

  1. BeanFactoryPostProcessor

  • 实际案例

CustomAutowireConfigurer允许用户自定义注解标签,该注解同样会被Spring解析。当同一个接口存在多个实现类时,被自定义注解标记的优先级更高。

/*
 * Copyright 2002-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.annotation;

import java.lang.annotation.Annotation;
import java.util.Set;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;

/**
 * A {@link org.springframework.beans.factory.config.BeanFactoryPostProcessor}
 * implementation that allows for convenient registration of custom autowire
 * qualifier types.
 *
 * <pre class="code">
 * &lt;bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer"&gt;
 *   &lt;property name="customQualifierTypes"&gt;
 *     &lt;set&gt;
 *       &lt;value&gt;mypackage.MyQualifier&lt;/value&gt;
 *     &lt;/set&gt;
 *   &lt;/property&gt;
 * &lt;/bean&gt;</pre>
 *
 * @author Mark Fisher
 * @author Juergen Hoeller
 * @since 2.5
 * @see org.springframework.beans.factory.annotation.Qualifier
 */
public class CustomAutowireConfigurer implements BeanFactoryPostProcessor, BeanClassLoaderAware, Ordered {

    private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered

    @Nullable
    private Set<?> customQualifierTypes;

    @Nullable
    private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();


    public void setOrder(int order) {
        this.order = order;
    }

    @Override
    public int getOrder() {
        return this.order;
    }

    @Override
    public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
        this.beanClassLoader = beanClassLoader;
    }

    /**
     * Register custom qualifier annotation types to be considered
     * when autowiring beans. Each element of the provided set may
     * be either a Class instance or a String representation of the
     * fully-qualified class name of the custom annotation.
     * <p>Note that any annotation that is itself annotated with Spring's
     * {@link org.springframework.beans.factory.annotation.Qualifier}
     * does not require explicit registration.
     * @param customQualifierTypes the custom types to register
     */
    public void setCustomQualifierTypes(Set<?> customQualifierTypes) {
        this.customQualifierTypes = customQualifierTypes;
    }


    @Override
    @SuppressWarnings("unchecked")
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        if (this.customQualifierTypes != null) {
            if (!(beanFactory instanceof DefaultListableBeanFactory)) {
                throw new IllegalStateException(
                        "CustomAutowireConfigurer needs to operate on a DefaultListableBeanFactory");
            }
            DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
            if (!(dlbf.getAutowireCandidateResolver() instanceof QualifierAnnotationAutowireCandidateResolver)) {
                dlbf.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
            }
            QualifierAnnotationAutowireCandidateResolver resolver =
                    (QualifierAnnotationAutowireCandidateResolver) dlbf.getAutowireCandidateResolver();
            for (Object value : this.customQualifierTypes) {
                Class<? extends Annotation> customType = null;
                if (value instanceof Class) {
                    customType = (Class<? extends Annotation>) value;
                }
                else if (value instanceof String) {
                    String className = (String) value;
                    customType = (Class<? extends Annotation>) ClassUtils.resolveClassName(className, this.beanClassLoader);
                }
                else {
                    throw new IllegalArgumentException(
                            "Invalid value [" + value + "] for custom qualifier type: needs to be Class or String.");
                }
                if (!Annotation.class.isAssignableFrom(customType)) {
                    throw new IllegalArgumentException(
                            "Qualifier type [" + customType.getName() + "] needs to be annotation type");
                }
                resolver.addQualifierType(customType);
            }
        }
    }

}
  1. BeanPostProcessor

  • 实际案例

  • ApplicationContextAwareProcessor,将实现*Aware接口的Bean注入相关的实例。

  • Spring AOP实现,AbstractAutoProxyCreator。

  1. 例子

  • User

package com.spring.xml.loading.entity;

public class User {
    private Long id;
    private String name;

    public void print(){
        System.out.println();
        System.out.println("User.print()");
    }
}
  • CustomizedBeanDefinitionRegistryPostProcessor

package com.spring.xml.loading.processor;

import com.spring.xml.loading.entity.User;
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;

public class CustomizedBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println();
        System.out.println("----------CustomizedBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()");
        System.out.println();
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(User.class);
        BeanDefinition beanDefinition = builder.getBeanDefinition();
        registry.registerBeanDefinition("user",beanDefinition);
    }

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

    }
}
  • CustomizedBeanFactoryPostProcessor

package com.spring.xml.loading.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

public class CustomizedBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println();
        System.out.println("----------CustomizedBeanFactoryPostProcessor.postProcessBeanFactory()");
        System.out.println();
    }
}
  • CustomizedBeanPostProcessor

package com.spring.xml.loading.processor;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class CustomizedBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println();
        System.out.println("CustomizedBeanPostProcessor.postProcessBeforeInitialization(),beanName = " + beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println();
        System.out.println("CustomizedBeanPostProcessor.postProcessAfterInitialization(),beanName = " + beanName);
        System.out.println();
        return bean;
    }
}
  • XML配置

spring_post_processor.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="customizedBeanDefinitionRegistryPostProcessor"
          class="com.spring.xml.loading.processor.CustomizedBeanDefinitionRegistryPostProcessor"/>

    <bean id="customizedBeanFactoryPostProcessor"
          class="com.spring.xml.loading.processor.CustomizedBeanFactoryPostProcessor"/>

    <bean id="customizedBeanPostProcessor"
          class="com.spring.xml.loading.processor.CustomizedBeanPostProcessor"/>

</beans>
  • Main

package com.spring.xml.loading;

import com.spring.xml.loading.entity.User;
import com.spring.xml.loading.service.UserService;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestPostProcessor {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring_post_processor.xml");
        User user = applicationContext.getBean("user",User.class);
        System.out.println(user);
        user.print();

    }
}
  • 输出

----------CustomizedBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()

----------CustomizedBeanFactoryPostProcessor.postProcessBeanFactory()

CustomizedBeanPostProcessor.postProcessBeforeInitialization(),beanName = user

CustomizedBeanPostProcessor.postProcessAfterInitialization(),beanName = user

com.spring.xml.loading.entity.User@79b06cab

User.print()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值