这里画了Bean加载简版流程图。主要是为了搞清楚几个扩展加载顺序。
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);
}
}
}
在容器完成所有Bean必要的属性填充完成之后,实现 Initialization
接口的Bean对象可以执行一些工作。Spring官方不推荐使用 Initialization
接口,因为这样会让代码和Spring耦合。最好使用 @PostConstruct
注解。
在容器销毁时,实现 Destruction
接口的Bean对象执行一些工作。同样官方推荐使用 @PreDestroy
注解。
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;
}
BeanFactoryPostProcessor
也是Spring提供的一个扩展点。我们可以基于这个扩展点去修改 BeanDefinitions。Spring执行 BeanFactoryPostProcesser
的方法时,Spring容器还没有对Beans进行创建、实例化。PropertyResourceConfigurer
类扩展该接口。
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
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;