Spring註解驅動開發——bean的後置處理器
BeanPostProcessor:是一個介面,bean的後置處理器(實際是在bean的初始化前後執行操作)
public class MyBeanPostProcessor implements BeanPostProcessor{ /** * bean是容器呼叫構造器建立的例項 * beanName是例項的id * 在所有初始化方法之前呼叫 */ public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** * bean是容器呼叫構造器建立的例項 * beanName是例項的id * 在所有初始化方法之後呼叫 */ public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
將MyBeanPostProcessor納入到容器中:
@Configuration
@Import(MyBeanPostProcessor.class)
public class LifeCycleConfig {
@Bean(initMethod="init0",destroyMethod="destroy0")
public Car car(){
return new Car();
}
}
這樣該容器中的所有bean在初始化前後都會執行該後置處理器中的邏輯,即使未定義初始化方法這些邏輯也會執行的,由此可以猜測:BeanPostProcessor可能是面向切面的
通過檢視原始碼,整個邏輯是這樣的:
在呼叫構造器之後,會為物件的所有屬性賦值,賦值完成後會呼叫初始化方法,但是在呼叫初始化方法時會進入一個切面,完成在初始化的前後執行BeanPostProcessor的邏輯:容器會遍歷所有的BeanPostProcessor並依次執行每個後置處理器的前置方法(postProcessBeforeInitialization),直至全部執行完或者其中一個該類方法返回null,然後完成Bean的初始化,初始化完成後,容器會繼續遍歷執行所有的BeanPostProcessor的後置方法(postProcessAfterInitialization),直至全部執行完或者其中一個該方法返回null
JDK1.8之後interface也可以有方法體了,子類也可以不實現介面中已有方法體的方法:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
BeanPostProcessor在Spring底層的使用:
①元件通過實現ApplicationContextAware介面獲取IOC容器,其實是ApplicationContextAwareProcessor在起作用
@Component
public class ContextBean implements ApplicationContextAware {
private ApplicationContext context;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
}
怎麼獲取到的IOC容器呢?容器在呼叫Bean的構造器並給所有屬性賦值之後,在執行所有初始化方法之前和之後,會執行一些BeanPostProcessor介面的子類中的邏輯,比如ApplicationContextAwareProcessor,在執行ApplicationContextAwareProcessor的postProcessBeforeInitialization()方法時,會判斷Bean是否實現了ApplicationContextAware介面,然後注入相應的ApplicationContext容器給Bean使用
②對元件的屬性進行校驗的BeanValidationPostProcessor
③InitDestroyAnnotationBeanPostProcessor:掃描Bean中標註了@PostConstruct和@PreDestroy註解的方法並執行,這也就是為什麼@PostConstruct標註的初始化方法在其他初始化方法之前執行
④AutowiredAnnotationBeanPostProcessor:為bean中標註了@Autowired註解的屬性賦值,這就是為什麼可以在init()方法中使用@Autowired註解的屬性的原因,因為在呼叫init方法之前會將這些屬性的值注入
⑤AsyncAnnotationBeanPostProcessor:使標註了@Async的方法非同步執行