(二十三)扩展原理-BeanFactoryPostProcessor

结论先行

  扩展原理:
  BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的
 
  1、BeanFactoryPostProcessor:beanFactory的后置处理器;
  		在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容;
  		所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建
 
 
  BeanFactoryPostProcessor原理:
  1)、ioc容器创建对象
  2)invokeBeanFactoryPostProcessors(beanFactory);
  		如何找到所有的BeanFactoryPostProcessor并执行他们的方法(postProcessBeanFactory);
  			1)、直接在BeanFactory中通过beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)这个方法找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法
  			2)、在初始化创建/初始化其他组件(finishBeanFactoryInitialization(beanFactory)这个方法)前面执行

BeanFactoryPostProcessor子类

package com.ouyangxizhu.ext;

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

import java.util.Arrays;

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory...");
		int count = beanFactory.getBeanDefinitionCount();
		String[] names = beanFactory.getBeanDefinitionNames();
		System.out.println("当前BeanFactory中有"+count+" 个Bean");
		System.out.println(Arrays.asList(names));
	}

}

配置类

package com.ouyangxizhu.ext;

import com.ouyangxizhu.bean.Blue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan("com.ouyangxizhu.ext")
@Configuration
public class ExtConfig {

	@Bean
	public Blue blue(){
		return new Blue();
	}

}

启动类

package com.ouyangxizhu;

import com.ouyangxizhu.ext.ExtConfig;
import com.ouyangxizhu.tx.TxConfig;
import com.ouyangxizhu.tx.UserService;
import com.ouyangxizhu.utils.PrintBeanDefinitionNamesUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTestExt {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ExtConfig.class);
        PrintBeanDefinitionNamesUtils.printBeanNames(context);
    }
}

工具类

package com.ouyangxizhu.utils;

import com.ouyangxizhu.config.MainConfigImport;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class PrintBeanDefinitionNamesUtils {
    public static void printBeanNames(Class<?> clazz) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(clazz);
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        System.out.println("===========");
        System.out.println("共有" + beanDefinitionNames.length + "个bean");
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
    public static void printBeanNames(AnnotationConfigApplicationContext context) {
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        System.out.println("===========");
        System.out.println("共有" + beanDefinitionNames.length + "个bean");
        for (String name : beanDefinitionNames) {
            System.out.println(name);
        }
    }
}

结果

八月 07, 2020 7:02:56 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@377dca04: startup date [Fri Aug 07 19:02:56 CST 2020]; root of context hierarchy
MyBeanFactoryPostProcessor...postProcessBeanFactory...
当前BeanFactory中有9 个Bean
[org.springframework.context.annotation.internalConfigurationAnnotationProcessor, org.springframework.context.annotation.internalAutowiredAnnotationProcessor, org.springframework.context.annotation.internalRequiredAnnotationProcessor, org.springframework.context.annotation.internalCommonAnnotationProcessor, org.springframework.context.event.internalEventListenerProcessor, org.springframework.context.event.internalEventListenerFactory, extConfig, myBeanFactoryPostProcessor, blue]
八月 07, 2020 7:02:56 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
blue...constructor
=====================
===========
共有9个bean
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
extConfig
myBeanFactoryPostProcessor
blue

结果解析

postProcessBeanFactory方法调用在类初始化之前,blue的定义在beanFactory中已经有了,但是还没初始化,接下来从这个类的方法定义中找解释和答案

BeanFactoryPostProcessor类的postProcessBeanFactory方法定义

/*
 * Copyright 2002-2012 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
 *
 *      http://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.config;

import org.springframework.beans.BeansException;

/**
 * Allows for custom modification of an application context's bean definitions,
 * adapting the bean property values of the context's underlying bean factory.
 *
 * <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
 * their bean definitions and apply them before any other beans get created.
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context.
 *
 * <p>See PropertyResourceConfigurer and its concrete implementations
 * for out-of-the-box solutions that address such configuration needs.
 *
 * <p>A BeanFactoryPostProcessor may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 *
 * @author Juergen Hoeller
 * @since 06.07.2003
 * @see BeanPostProcessor
 * @see PropertyResourceConfigurer
 */
public interface BeanFactoryPostProcessor {

	/**
	*在bean factory标准初始化之后修改IOC容器中的内部bean factory
	 * Modify the application context's internal bean factory after its standard
	 * //所有的bean定义已经被加载了,但是没有bean被实例化
	 * initialization. All bean definitions will have been loaded, but no beans
	 * will have been instantiated yet. This allows for overriding or adding
	 * properties even to eager-initializing beans.
	 * @param beanFactory the bean factory used by the application context
	 * @throws org.springframework.beans.BeansException in case of errors
	 */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值