9. Spring Bean 生命周期

9. Spring Bean 生命周期,第1张

9.1 Spring Bean 元信息配置阶段
  • 面向资源

    • XML 配置

    • Properties 配置

  • 面向注解

  • 面向 API

基于 Properties 配置元信息举例:

public class BeanMetadataConfigurationDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(factory);
        System.out.println(reader.loadBeanDefinitions("user.properties"));
​
        System.out.println(factory.getBean(User.class));
        System.out.println(Arrays.toString(factory.getBeanDefinitionNames()));
    }
}
usr.(class)=com.gcl.bean.lifecycle.bean.User
usr.name=foo
usr.age=1
9.2 Spring Bean 元信息解析阶段
  • 面向资源 BeanDefinition 解析

    • BeanDefinitionReader

    • XML 解析器——BeanDefinitionParser

  • 面向注解 BeanDefinition 解析

    • annotatedBeanDefinition

面向注解 BeanDefinition 解析举例:

public class AnnotatedBeanDefinitionParsingDemo {

    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        // 基于 Java 注解的 AnnotatedBeanDefinitionReader 实现
        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(factory);
        // 注册类
        reader.register(AnnotatedBeanDefinitionParsingDemo.class, User.class);

        // 普通 Class 作为 Component 注册到 Spring IoC 容器后,通常 Bean 名称为类名首字母小写
        // Bean 名称生成来自于 BeanNameGenerator,注解实现 AnnotationBeanNameGenerator
        System.out.println(factory.getBean("annotatedBeanDefinitionParsingDemo", AnnotatedBeanDefinitionParsingDemo.class));
        System.out.println(factory.getBean("user", User.class));
    }
}
9.3 Spring Bean 注册阶段

Bean 注册是在 DefaultListableBeanFactory#registerBeanDefinition 中进行的,默认允许覆盖(重复注册),内部有两个数据结构:

/** Map of bean definition objects, keyed by bean name. */
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);
/** List of bean definition names, in registration order. */
private volatile List beanDefinitionNames = new ArrayList<>(256);

map 用于保存 BeanDefinition 和 name,list 用于顺序保存 Bean 的name,为后续实例化提供顺序(map无序)

9.4 Spring BeanDefinition 合并阶段

Spring 中 BeanDefinition 有两种类型:root 和 generic,其中 root 表示没有 parent,generic 则可有可不有,Spring 中 BeanDefiniton 的合并就是针对 generic 类型 BeanDefinition,如果有 parent,则将 parent 属性合并到 generic 中,当然该 *** 作是一个递归的 *** 作,会一直递归合并直到 root 或者直到 BeanDefinition 没有 parent 为止。

合并过程在 AbstractBeanFactory#getMergedBeanDefinition 中实现(唯一实现)

public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
    String beanName = transformedBeanName(name);
    // Efficiently check whether bean definition exists in this factory.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
    }
    // Resolve merged bean definition locally.
    return getMergedLocalBeanDefinition(beanName);
}

找到存在该 BeanDefinition 定义的 BeanFactory,从中进行合并 *** 作

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
    // Quick check on the concurrent map first, with minimal locking.
    RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
    if (mbd != null && !mbd.stale) {
        return mbd;
    }
    return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
​
/** Map from bean name to merged RootBeanDefinition. */
private final Map mergedBeanDefinitions = new ConcurrentHashMap<>(256);

会将 mbd 保存在 mergedBeanDefinitions 中,如果存在,直接返回,否则进行合并

合并过程首先判断该 BeanDefinition 是否有 parent,如果没有,则用当前 BeanDefinition 创建一个 RootBeanDefinition,否则查询其 parent,利用其 parent BeanDefinition 创建 RootBeanDefinition,并且将子 BeanDefinition 和其合并,合并中利用子类已有的配置覆盖父类中的配置,即配置优先级为子类 > 父类。

9.5 Spring Bean Class 加载阶段

Spring Bean Class 加载通过 Java 的 ClassLoader 进行,通过 XML 配置的 BeanDefinition,其 beanClass 初始为 String,经过 ClassLoader 加载以后变成 Class 类型,并且此时 AbstractBeanDefinition#hasBeanClass 为 true

9.6 Spring Bean 实例化前阶段
public class BeanInstantiationLifecycleDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
​
        reader.loadBeanDefinitions("merged-bean-definition.xml");
​
        System.out.println(factory.getBean("superUser"));
    }
​
    static class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
            if (beanName.equals("superUser") && beanClass == SuperUser.class) {
                return new SuperUser();
            }
            return null;
        }
    }
}

该方法并不常用,因为该方法执行后,后续的实例化过程就不会执行

9.7 Spring Bean 实例化阶段
  • 传统方式

    • 实例化策略——InstantiationStrategy

  • 构造器依赖注入

AbstractBeanFactory#getBean ->

AbstractBeanFactory#doGetBean -> 得到 mbd,然后通过 mbd、beanName 以及 args 创建对象

AbstractBeanFactory#createBean ->

AbstractAutowireCapableBeanFactory#createBean ->

AbstractAutowireCapableBeanFactory#doCreateBean -> 返回 BeanWrapper,将对象包装成 BeanWrapper 后返回

AbstractAutowireCapableBeanFactory#createBeanInstance -> 构造器自动注入还是无参构造器创建对象

AbstractAutowireCapableBeanFactory#instantiateBean -> 获取策略实例化对象,默认cglib

CglibSubclassingInstantiationStrategy#instantiate -> cglib策略创建对象,调用父类策略创建对象

SimpleInstantiationStrategy#instantiate -> 此处通过反射创建对象

9.8 Spring Bean 实例化后阶段

InstantiationAwareBeanPostProcessor#postProcessorAfterInstantiation

该阶段决定 Bean 是否允许对属性进行赋值,默认允许

public class BeanInstantiationLifecycleDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
​
        reader.loadBeanDefinitions("merged-bean-definition.xml");
​
        System.out.println(factory.getBean("superUser"));
        System.out.println(factory.getBean("user"));
    }
​
    static class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        // 此处默认返回null,如果返回不为null,则表示后续的实例化过程不用进行,使用返回的对象当作bean进行注入
        // 该方法跟后续的 postProcessAfterInstantiation 互斥
        public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
            if (beanName.equals("superUser") && beanClass == SuperUser.class) {
                return new SuperUser();
            }
            return null;
        }
​
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            // 默认返回 true,表示允许属性赋值,此处将 User 对象设置为 false,表示不允许对名称为"user",类型为User的对象赋值
            return !beanName.equals("user") || bean.getClass() != User.class;
        }
    }
}
​
// 运行结果:
SuperUser{level=0} User{name='null', age=0}
User{name='null', age=0}



    
        
        
    

    
        
    
9.9 Spring Bean 属性赋值前阶段
  • Bean 属性元信息

    • PropertyValues

  • Bean 属性赋值前回调

    • Spring 1.2-5.0:InstantiationAwareBeanPostProcessor#postProcessPropertyValues

    • Spring 5.1:InstantiationAwareBeanPostProcessor#postProcessProperties

注意:如果 postProcessAfterInstantiation 方法返回 false,则该回调不会被调用,是互斥的。

postProcessBeforeInstantiation 方法如果返回对象不为 null,则不仅会跳过 postProcessAfterInstantiation 方法,同时还会跳过 postProcessProperties 方法,因为完全跳过实例化整个过程,所以后续有关实例化的所有回调都会被忽略

public class BeanInstantiationLifecycleDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

        reader.loadBeanDefinitions("merged-bean-definition.xml");

        System.out.println(factory.getBean("superUser"));
        System.out.println(factory.getBean("user"));
    }

    static class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            if (ObjectUtils.nullSafeEquals("user", beanName) && bean.getClass() == User.class) {
                //假设  在 XML 中配置,那么此处 pvs 中有一个 PropertyValue(name="foo")
                MutablePropertyValues propertyValues = null;
                if (pvs instanceof MutablePropertyValues) {
                    propertyValues = (MutablePropertyValues) pvs;
                } else {
                    propertyValues = new MutablePropertyValues();
                }
                // 等价于 ,不允许配置不存在的属性,不然报错
                propertyValues.addPropertyValue("name", "bar");
                propertyValues.addPropertyValue("age", "19");
                return propertyValues;
            }
            return null;
        }
    }
}

// 运行结果:
SuperUser{level=1} User{name='foo', age=18}
User{name='bar', age=19}
9.10 Spring Bean Aware 接口回调阶段(属于初始化阶段)

Spring Aware 接口:(接口注入)(按照执行顺序排列)

  • BeanNameAware

  • BeanClassLoaderAware

  • BeanFactoryAware

  • EnvironmentAware

  • EmbeddedValueResolverAware

  • ResourceLoaderAware

  • ApplicationEventPublisherAware

  • MessageSourceAware

  • ApplicationContextAware

从 EnvironmentAware 开始,隶属 ApplicationContext 生命周期,因此只使用 BeanFactory 是无法注入这些 Bean 的。即 BeanFactory 只能注入前三个 Aware 回调,ApplicationContext 则可以注入所有回调。

class ApplicationContextAwareProcessor implements BeanPostProcessor {

	private final ConfigurableApplicationContext applicationContext;

	private final StringValueResolver embeddedValueResolver;


	/**
	 * Create a new ApplicationContextAwareProcessor for the given context.
	 */
	public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
		this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
	}


	@Override
	@Nullable
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof EnvironmentAware) {
			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
		}
		if (bean instanceof EmbeddedValueResolverAware) {
			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
		}
		if (bean instanceof ResourceLoaderAware) {
			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
		}
		if (bean instanceof ApplicationEventPublisherAware) {
			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
		}
		if (bean instanceof MessageSourceAware) {
			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
		}
		if (bean instanceof ApplicationContextAware) {
			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
		}
	}

} 

AbstractApplicationContext#prepareBeanFactory 方法中通过 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); 添加上面的 Processor

9.11 Spring Bean 初始化前阶段
  • 已完成

    • Bean 实例化

    • Bean 属性赋值

    • Bean Aware 接口回调

  • 方法回调

    • BeanPostProcessor#postProcessorBeforeInitialization

9.12 Spring Bean 初始化阶段
  • @PostContructor

  • 实现 InitializingBean 接口的 afterProperties 方法

  • 自定义初始化方法

public class BeanInitializationLifecycleDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        factory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor());

        reader.loadBeanDefinitions("merged-bean-definition.xml");

        System.out.println(factory.getBean("user"));
    }
}



    
        
        
    

    
        
    
9.13 Spring Bean 初始化后阶段

BeanPostProcessor#postProcessorAfterInitialization

初始化方法 AbstractAutowireCapableBeanFactory#initializeBean,该方法中调用了四个方法

  • invokeAwareMethods

  • applyBeanPostProcessorsBeforeInitialization

  • invokeInitMethods

  • applyBeanPostProcessorsAfterInitialization

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

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

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

    return wrappedBean;
} 

因此生命周期会按照上述来进行。

9.14 Spring Bean 初始化完成阶段

Spring 4.1+:SmartInitializingSingleton#afterSingletonsInstantiated

public class BeanInstantiationLifecycleDemo {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

        reader.loadBeanDefinitions("merged-bean-definition.xml");

        factory.preInstantiateSingletons();

        System.out.println(factory.getBean("user"));
    }
}

public class User implements InitializingBean, SmartInitializingSingleton {
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @PostConstruct
    public void postConstructor() {
        System.out.println("post");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("initialization bean");
    }

    public void init() {
        System.out.println("init-method");
    }

    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("after");
    }
}

// 运行结果:
initialization bean
init-method
initialization bean
init-method
after
after
User{name='bar', age=19}

使用 SmartInitializingSingleton 要么在 ApplicaitonContext 场景中使用,如果在 BeanFactory 场景中使用,需要手动调用 preInstantiateSingletons 方法触发 Bean 的实例化,在该方法中会通过 beanDefinitionNames 依次进行初始化 *** 作

public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }
​
    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List beanNames = new ArrayList<>(this.beanDefinitionNames);
​
    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    final FactoryBean factory = (FactoryBean) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction)
                                                                    ((SmartFactoryBean) factory)::isEagerInit,
                                                                    getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                       ((SmartFactoryBean) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                // 此处执行 Bean 的初始化 *** 作,初始化 Bean 中首先会创建依赖 Bean,创建完以后,再执行实例化 *** 作
                // 实例化 *** 作执行过程中,会创建 BeanWrapper,实例化后通过 populateBean 执行属性赋值,调用
                // InstantiationAwareBeanPostProcessors
                // BeanPostProcessors
                // 属性赋值完以后调用 initializeBean 方法进行初始化
                // invokeAwareMethods
                // applyBeanPostProcessorsBeforeInitialization
                // invokeInitMethods:InitializingBean#afterPropertiesSet -> init-method
                // applyBeanPostProcessorsAfterInitialization
                getBean(beanName);
            }
        }
    }
​
    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                // 此处执行 Smart 的回调
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
} 
9.15 Spring Bean 销毁前阶段 
  • DestructionAwareBeanPostProcessor#postProcessBeforeDestruction

9.16 Spring Bean 销毁阶段
  • @PreDestroy(跟 DestructionAwareBeanPostProcessor 是在同一等级执行的)

  • 实现 DisposableBean 接口的 destroy 方法

  • 自定义销毁方法

销毁最终调用 DisposableBeanAdapter#destroy 方法进行

@Override
public void destroy() {
    if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
        for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
            // @PreConstructor 和 实现了 DestructionAwareBeanPostProcessor 接口的销毁逻辑在这里执行
            processor.postProcessBeforeDestruction(this.bean, this.beanName);
        }
    }

    // 实现 DispoableBean 接口的销毁逻辑在这里执行
    if (this.invokeDisposableBean) {
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
        }
        try {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedExceptionAction) () -> {
                    ((DisposableBean) this.bean).destroy();
                    return null;
                }, this.acc);
            }
            else {
                ((DisposableBean) this.bean).destroy();
            }
        }
        catch (Throwable ex) {
            String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
            if (logger.isDebugEnabled()) {
                logger.warn(msg, ex);
            }
            else {
                logger.warn(msg + ": " + ex);
            }
        }
    }

    // 自定义销毁方法在这里执行
    if (this.destroyMethod != null) {
        invokeCustomDestroyMethod(this.destroyMethod);
    }
    else if (this.destroyMethodName != null) {
        Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
        if (methodToInvoke != null) {
            invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
        }
    }
} 
9.17 Spring Bean 垃圾收集阶段 
  • 关闭 Spring 容器(应用上下文)

  • 执行GC

  • Spring Bean 覆盖的 finalize 方法被回调(不保证一定被执行)

9.18 面试题

9.18.1 BeanPostProcessor 使用场景

BeanPostProcessor 提供 Spring Bean 初始化前和初始化后的生命周期回调,分别对应 postProcessBeforeInitialization 以及 postProcessAfterInitialization 方法,允许对关心的 Bean 进行扩展,甚至是替换

其中 ApplicationContext 相关的 Aware 回调也是基于 BeanPostProcessor 实现的,即 ApplicationContextAwareProcessor

BeanPostProcessor 针对所有 Bean,所有 Bean 初始化都会走这里的逻辑(前提是进行了自定义实现以及注入),可以在 Bean 实例化前后加入一些 *** 作,例如 ApplicationContextAwareProcessor 做法如下:

class ApplicationContextAwareProcessor implements BeanPostProcessor {
​
    private final ConfigurableApplicationContext applicationContext;
​
    private final StringValueResolver embeddedValueResolver;
​
​
    /**
     * Create a new ApplicationContextAwareProcessor for the given context.
     */
    public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    }
​
​
    @Override
    @Nullable
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
            return bean;
        }
​
        AccessControlContext acc = null;
​
        if (System.getSecurityManager() != null) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }
​
        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }
​
        return bean;
    }
​
    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
​
} 

会拦截所有 bean,如果 bean 实现了上面六种接口中至少一种,就进行响应的 aware 回调处理

9.18.2 BeanFactoryPostProcessor 和 BeanPostProcessor 区别

BeanFactoryPostProcessor 是 Spring BeanFactory(实际为 ConfigurableListableBeanFatory)的后置处理器,用于扩展 BeanFactory,或通过 BeanFactory 进行依赖查找和依赖注入

BeanFactoryPostProcessor 必须有 Spring ApplicationContext 执行,BeanFactory 无法直接于其进行交互

而 BeanPostProcessor 则直接与 beanFactory 关联,属于 N 对 1 的关系

public interface BeanFactoryPostProcessor {
​
    /**
     * Modify the application context's internal bean factory after its standard
     * 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;
​
}

从接口定义可知,该接口方法被回调时是 BeanDefiniton 都加载完成但还没有任何一个 Bean 进行实例化,此时可以对 BeanFactory 进行一定的 *** 作

  • 增加 BeanPostProcessor

  • 依赖查找或依赖注入

通过 AbstractApplicationContext#refresh 方法中 invokeBeanFactoryPostProcessors 方法启动

BeanFactory 只能手动添加 BeanPostProcessor,但是在 ApplicationContext 中,在 AbstractApplicationContext#refresh 方法中会通过方法 registerBeanPostProcessors 来进行自动的扫描和注册

BeanPostProcessor 可以为其指定顺序 Order,可通过 @Order 注解、实现 Ordered 接口或者 PriorityOrdered 接口来指定顺序

9.18.3 BeanFactory 如何处理 Bean 生命周期

BeanFactory 默认实现为 DefaultListableBeanFactory,其中 Bean 生命周期与方法映射如下:

  • BeanDefinition 注册阶段——registerBeanDefinition

  • BeanDefinition 合并阶段——getMergedBeanDefinition

  • Bean 实例化前阶段——resolveBeforeInstantiation

  • Bean 实例化阶段——createBeanInstacence

  • Bean 实例化后阶段——populateBean

  • Bean 属性赋值前阶段——populateBean

  • Bean 属性复制阶段——populateBean

  • Bean Aware 接口回调阶段——initializeBean

  • Bean 初始化前阶段——initializeBean

  • Bean 初始化阶段——initializeBean

  • Bean 初始化后阶段——initializeBean

  • Bean 初始化完成阶段——preInstrantiateSingletons

  • Bean 销毁前阶段——destroyBean

  • Bean 销毁阶段——destroyBean

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/869220.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)