Spring Bean生命周期(一)

Spring组件生命周期粗略来说有四个阶段:
实例化>属性赋值>初始化>销毁

后置处理器

说到生命周期,不得不提后置处理器,有两个非常重要的接口

在这里插入图片描述
InstantiationAwareBeanPostProcessor:主要作用于实例创建前后
BeanPostProcessor:作用于Bean初始化前后
看个图来深刻理解下
在这里插入图片描述

后置处理器的使用
BeanPostProcessor

写一个类继承BeanPostProcessor接口,并注册到容器中

/**
 *容器初始化Bean都会被该后置处理器影响
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    /**
     * 初始化前执行
     * @param bean 注册的Bean
     * @param beanName 注册的Bean的name
     * @return
     * @throws BeansException
     */
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization=>"+beanName);
        //可对Bean进行包装处理等工作后返回
        return bean;
    }
    //初始化后执行  其他同上
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization=>"+beanName);
        return bean;
    }
}

这样在Bean初始化前后都会分别打印beanName
在这里插入图片描述

InstantiationAwareBeanPostProcessor

通常用于禁止特定目标Bean的默认实例化,例如,使用特殊的TargetSource创建代理(合并目标,延迟初始化目标等),或实施其他注入策略。
写一个类继承BeanPostProcessor接口,并注册到容器中

@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
	 /*
    返回的bean对象可以是要使用的代理,而不是目标bean,
    有效抑制目标Bean的默认实例化。
    返回不能为Null否则抛异常。
     */
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInstantiation=>"+beanName);
        return null;
    }
	 /*
    此时Bean已经实例化
    返回值决定是否要调用   postProcessPropertyValues   true调用  否则反之
     */
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInstantiation=>"+beanName);
        return true;
    }
  	/*
    根据需求为Bean赋值
    */
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        System.out.println("postProcessPropertyValues=>"+pvs);
        return null;
    }

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

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization=>"+beanName);
        return bean;
    }
}

初始化Ioc容器查看控制台输出内容
在这里插入图片描述

在Spring中的运用

后置处理器在Spring中也大量的运用。
举个例子:ApplicationContextAwareProcessor
这是Spring定义获取上下文的后置处理器
下方为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
	public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			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);
			}
		}
	}

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

}

可以看到初始化中调用invokeAwareInterfaces判断bean是否为ApplicationContextAware如果是的话就把上下文传递过去。
只要继承ApplicationContextAware接口就可以获取到上下文。

@Component
public class Animal implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    //Bean在初始化时前   会被ApplicationContextAwareProcessor调用   从而获得上下文
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

另外Spring中有大量的Aware结尾的接口,通常这些接口都是可以获取到Spring容器的相关信息的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值