第8章 Spring加载Bean流程以及常用扩展点

加载Bean流程

这里画了Bean加载简版流程图。主要是为了搞清楚几个扩展加载顺序。

第8章 Spring加载Bean流程以及常用扩展点_第1张图片

常用扩展点

1.Aware

Aware 接口都是用来感知的。

BeanNameAware 用来感知Bean对象被容器管理的beanName

BeanClassLoaderAware 可以给Bean对象设置类加载器

BeanFactoryAware 给Bean对象设置BeanFacory对象

Spring 在初始化Bean对象时,对Aware接口的处理

private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}
2.生命周期回调接口
Initialization Callbacks

在容器完成所有Bean必要的属性填充完成之后,实现 Initialization 接口的Bean对象可以执行一些工作。Spring官方不推荐使用 Initialization 接口,因为这样会让代码和Spring耦合。最好使用 @PostConstruct 注解。

DisposableBean Callbacks

在容器销毁时,实现 Destruction 接口的Bean对象执行一些工作。同样官方推荐使用 @PreDestroy 注解。

3.BeanPostProcessor

BeanPostProcessor 允许自定义修改新的Bean实例对象。例如可以对Bean实例进行代理。

BeanPostProcessor 将会被Spring自动注册到容器中,这些BeanPostProcessor的有顺序的,可以通过实现接口 Ordered 接口控制顺序。

Spring 初始化Bean时,对 BeanPostProcessor#postProcessBeforeInitialization 的处理。

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

Spring 初始化Bean时,对 BeanPostProcessor#postProcessAfterInitialization 的处理。

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}
4.BeanFactoryPostProcessor

BeanFactoryPostProcessor 也是Spring提供的一个扩展点。我们可以基于这个扩展点去修改 BeanDefinitions。Spring执行 BeanFactoryPostProcesser 的方法时,Spring容器还没有对Beans进行创建、实例化。PropertyResourceConfigurer 类扩展该接口。

@FunctionalInterface
public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
5.FactoryBean

FactoryBean 接口是用来提供自定义创建对象。FactoryBean 提供3个方法:

  • T getObject():返回由这个工厂创建的对象。这个对象可以是单例或者原型(prototypes),取决于 isSingleton 返回值。

  • boolean isSingleton():返回为true,表示返回单例对象

  • Class getObjectType():返回对象的Class实例。

Spring 容器仅去管理 FactoryBean 实例的生命周期,不会管理由 FactoryBean 创建的对象实例的生命周期。假设 FactoryBean 创建的对象实现了接口 Closeable.close() 的方法,将不会被自动调用。我们应该让Factory Bean 实现 DisposableBean 接口,然后再委派其实例关闭。

public interface FactoryBean<T> {

	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

	@Nullable
	T getObject() throws Exception;

	@Nullable
	Class<?> getObjectType();

	default boolean isSingleton() {
		return true;
	}

}

FactoryBean 只是一种Bean Style。如果想要从容器中获取 FactoryBean 的对象实例,getBean("&myBean")getBean("myBean") 获取得是由 FactoryBean 创建的对象实例。

public class MyBean implements FactoryBean<People> {
    @Override
	public People getObject() throws Exception {
		return new People();
	}

	@Override
	public Class<?> getObjectType() {
		return People.class;
	}
}
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:autowire.xml");
MyBean bean = context.getBean("&myBean", MyBean.class);
People bean2 = context.getBean("myBean", People.class);

System.out.println(bean);
System.out.println(bean2);
// com.example.MyBean
// com.example.People;

你可能感兴趣的:(Spring,spring,java,restful)