spring 后置处理器

spring 中的注解,比如@Autowired 、dubbo的@AutowiredDubbo,还有@Value等等的使用,是如何完成依赖注入的?

在spring中,有提供一类特殊的接口,叫做后置处理器

 这类接口提供给处理类,可以修改bean的值,或者在bean实例化过程中添加其他处理:

 

public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
}
public interface BeanPostProcessor {
    Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;

    Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}

 接下来分析一下后置处理器的使用。

 apollo在项目中的使用:

@SpringBootApplication
@ComponentScan(basePackages = (MobileOfficeApplication.keKeingPackages))
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@EnableJpaAuditing
@EnableApolloConfig
@EnableDubbo
@EnableAsync
@EntityScan({MobileOfficeApplication.keKeingPackages})
@EnableFeignClients(basePackages = (MobileOfficeApplication.keKeingPackages))
public class MobileOfficeApplication {

    static final String keKeingPackages = "cn.*.*";

    public static void main(String[] args) {
        SpringApplication.run(MobileOfficeApplication.class, args);
    }


}

 

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({ApolloConfigRegistrar.class})
public @interface EnableApolloConfig {
    String[] value() default {"application"};

    int order() default 2147483647;
}

 看这里的注解@Import({ApolloConfigRegistrar.class}),import注解用于引入bean,ApolloConfigRegistrar对象是apollo包下的。

public class ApolloConfigRegistrar implements ImportBeanDefinitionRegistrar {
    public ApolloConfigRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AnnotationAttributes attributes = AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(EnableApolloConfig.class.getName()));
        String[] namespaces = attributes.getStringArray("value");
        int order = (Integer)attributes.getNumber("order");
        PropertySourcesProcessor.addNamespaces(Lists.newArrayList(namespaces), order);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(), PropertySourcesPlaceholderConfigurer.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesProcessor.class.getName(), PropertySourcesProcessor.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(), ApolloAnnotationProcessor.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(), SpringValueProcessor.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueDefinitionProcessor.class.getName(), SpringValueDefinitionProcessor.class);
        BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloJsonValueProcessor.class.getName(), ApolloJsonValueProcessor.class);
    }
}

 registerBeanDefinitions方法中会注册多个对象,这些对象是用来做什么的呢?

public class SpringValueProcessor extends ApolloProcessor implements BeanFactoryPostProcessor 

 查看apollo源码

public abstract class ApolloProcessor implements BeanPostProcessor, PriorityOrdered {
public class PropertySourcesProcessor implements BeanFactoryPostProcessor, EnvironmentAware, PriorityOrdered 
public class ApolloJsonValueProcessor extends ApolloProcessor implements BeanFactoryAware 
public class SpringValueDefinitionProcessor implements BeanDefinitionRegistryPostProcessor
public class SpringValueProcessor extends ApolloProcessor implements BeanFactoryPostProcessor 
public class ApolloAnnotationProcessor extends ApolloProcessor
public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport implements EnvironmentAware

 apollo注册的bean对象,都有继承或者实现spring提供的接口。

 BeanFactoryPostProcessor和BeanPostProcessor这两个接口都是初始化bean时对外暴露的入口之一,BeanFactoryPostProcessor是bean工厂的bean属性处理容器,说通俗一些就是可以管理我们的bean工厂内所有的beandefinition(未实例化)数据,可以随心所欲的修改属性。

apollo功能最重要的一点就是动态的修改对象属性,那看到这里应该都会猜想功能的实现是跟BeanFactoryPostProcessor这个接口有关。

processField方法有处理Value注解,具体apollo的逻辑以后再细心研读分享一下。

protected void processField(Object bean, String beanName, Field field) {
        Value value = (Value)field.getAnnotation(Value.class);
        if (value != null) {
            Set<String> keys = this.placeholderHelper.extractPlaceholderKeys(value.value());
            if (!keys.isEmpty()) {
                Iterator var6 = keys.iterator();

                while(var6.hasNext()) {
                    String key = (String)var6.next();
                    SpringValue springValue = new SpringValue(key, value.value(), bean, beanName, field, false);
                    this.springValueRegistry.register(key, springValue);
                    logger.debug("Monitoring {}", springValue);
                }

            }
        }
    }

AutowiredDubbo处理相关代码: 

@Configuration
@ConditionalOnBean(
    annotation = {EnableDubbo.class}
)
@EnableConfigurationProperties({DubboConfiguration.class})
public class ConsumerAutoConfiguration implements BeanPostProcessor {
    private Logger logger = LoggerFactory.getLogger(ConsumerAutoConfiguration.class);
    private Map<String, Object> refrences = new ConcurrentHashMap();
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private DubboConfiguration configuration;

    public ConsumerAutoConfiguration() {
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Object current = bean;
        Class<?> clazz = bean.getClass();
        if (AopUtils.isAopProxy(bean)) {
            clazz = AopUtils.getTargetClass(bean);
        }

        try {
            if (AopUtils.isCglibProxy(bean)) {
                current = getCglibProxyTargetObject(bean);
            } else if (AopUtils.isJdkDynamicProxy(bean)) {
                current = getJdkDynamicProxyTargetObject(bean);
            }
        } catch (Exception var21) {
            this.logger.error("", var21);
        }

        try {
            Field[] var5 = clazz.getDeclaredFields();
            int var6 = var5.length;

            for(int var7 = 0; var7 < var6; ++var7) {
                Field field = var5[var7];
                AutowiredDubbo autowiredDubbo = (AutowiredDubbo)field.getAnnotation(AutowiredDubbo.class);
                if (autowiredDubbo != null) {
                    Class<?> type = field.getType();
                    ReferenceBean<?> dubboConsumer = this.initAutowiredDubboBean(type, autowiredDubbo);
                    String group = dubboConsumer.getGroup();
                    String version = dubboConsumer.getVersion();
                    String key = type + "_" + group + "_" + version;

 

那么后置处理又是如何生效的?

 在spring boot启动阶段,

 public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

 这里的方法就是调用所有BeanFactoryPostProcessor的postProcessBeanFactory方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

    }

 

 private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
        Iterator var2 = postProcessors.iterator();

        while(var2.hasNext()) {
            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
            postProcessor.postProcessBeanFactory(beanFactory);
        }

    }

上面介绍的是 BeanFactoryPostProcessor 接口的调用过程。

BeanPostProcessor 的实现原理跟踪:

 

  if (mbd.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
                        public Object getObject() throws BeansException {
                            try {
                                return AbstractBeanFactory.this.createBean(beanName, mbd, args);
                            } catch (BeansException var2) {
                                AbstractBeanFactory.this.destroySingleton(beanName);
                                throw var2;
                            }
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } else if (mbd.isPrototype()) {
                    var11 = null;

                    Object prototypeInstance;
                    try {
                        this.beforePrototypeCreation(beanName);
                        prototypeInstance = this.createBean(beanName, mbd, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }

                    bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }

继续跟踪到createBean—>doCreateBean—>initializeBean

这里看到applyBeanPostProcessorsBeforeInitialization 和applyBeanPostProcessorsAfterInitialization方法 

 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

 执行前置处理

 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if (!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        } while(result != null);

        return result;
    }

 执行后置处理

 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if (!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);

        return result;
    }

我们就找到了BeanPostProcessor 的处理过程了。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值