接AnnotationConfigApplicationContext流程看实例化的beanPostProcessor-CSDN博客,以具体实例看bean生命周期的一些执行阶段
bean生命周期流程
|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 生命周期 | 扩展处理 | 说明 |
| 实例化:createBeanInstance | 构造方法, 如@Autowired的构造方法注入依赖bean | 如UserService构造方法注入AppDAO: > > @Autowired > public UserService(AppDAO appDAO) { > System.out.println("@Autowired appDAO:" + appDAO); > this.appDAO = appDAO; > } >
|
| 属性设置:populateBean | 如setter方法注入的依赖 如@Autoware的filed注入 | 如UserService中注入UserDAO: > > @Resource(name = "u") > public void setUserDAO(UserDAO userDAO) { > System.out.println("setUserDAO:" + userDAO); > this.userDAO = userDAO; > } >
|
| 初始化:initializeBean | 1. BeanPostProcessor#postProcessBeforeInitialization 2. @PostConstruct 3. InitializingBean#afterPropertiesSet initMethod 4. BeanPostProcessor#postProcessAfterInitialization | 上一步骤属性设置完后,初始化方法前后都可以扩展。 例如BeanPostProcessor#postProcessBeforeInitialization,直接改变了set注入的appDAO对象 > > @Component > public class ServiceBeanPostProcessor implements BeanPostProcessor { > @Override > public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { > // Bean 初始化前的逻辑 > if (beanName.equals("userService")) { > UserService userService = (UserService)bean; > AppDAO appDAO = new AppDAOImpl2(); > userService.setAppDAO(appDAO); > System.out.println("postProcessBeforeInitialization:" + ":" + bean); > } > return bean; > } >
|
| 销毁 | 1. @PreDestroy 2. DisposableBean#destroy destroyMethod | |
附org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
java
/**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
扩展执行
接上文:AnnotationConfigApplicationContext流程看实例化的beanPostProcessor-CSDN博客,来看这些BeanPostProcessor如何起作用
测试bean定义类如下
java
@Service("userService")
public class UserService implements InitializingBean, DisposableBean {
private String userServiceName;
private UserDAO userDAO;
private AppDAO appDAO;
/**
* field 注入
*/
@Autowired
private CommonService commonService;
public UserService() {
System.out.println("constructor");
}
/**
* 类似于 InitializingBean 的 afterPropertiesSet() 方法
*/
@PostConstruct
public void init() {
System.out.println("PostConstruct userService");
System.out.println("userDAO is not null:" + (userDAO != null));
System.out.println("appDAO is not null:" + (appDAO != null));
userServiceName = "selfUserService";
}
/**
* setter注入
* @param userDAO
*/
@Resource(name = "u")
public void setUserDAO(UserDAO userDAO) {
System.out.println("setUserDAO:" + userDAO);
this.userDAO = userDAO;
}
/**
* 构造器注入
* @param appDAO
*/
@Autowired
public UserService(AppDAO appDAO) {
System.out.println("@Autowired appDAO:" + appDAO);
this.appDAO = appDAO;
}
public void add(User user) {
userDAO.save(user);
}
public UserDAO getUserDAO() {
return userDAO;
}
/**
* 类似于 DisposableBean 的 destroy() 方法
*/
@PreDestroy
public void preDestroy() {
System.out.println("preDestroy");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet userService");
}
@Override
public void destroy() throws Exception {
System.out.println("destroy userService");
}
public void setUserServiceName(String userServiceName) {
this.userServiceName = userServiceName;
}
public void setAppDAO(AppDAO appDAO) {
this.appDAO = appDAO;
}
@Override
public String toString() {
return "UserService{" +
"userServiceName='" + userServiceName + '\'' +
", userDAO=" + userDAO +
", appDAO=" + appDAO +
", commonService=" + commonService +
'}';
}
}
InstantiationAwareBeanPostProcessors:SmartInstantiationAwareBeanPostProcessor
推断构造函数,最后是AutowiredAnnotationBeanPostProcessor完成构造函数的推断
最后判断有@Autowired的构造函数 完成实例化过程
InstantiationAwareBeanPostProcessor:CommonAnnotationBeanPostProcessor
populate阶段CommonAnnotationBeanPostProcessor完成setter注入
/** * setter注入 * @param userDAO */ @Resource(name = "u") public void setUserDAO(UserDAO userDAO) { System.out.println("setUserDAO:" + userDAO); this.userDAO = userDAO; }
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties
java
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
InstantiationAwareBeanPostProcessor:AutowiredAnnotationBeanPostProcessor
populate阶段AutowiredAnnotationBeanPostProcessor完成@Autorwired的filed的注入,具体可以再次阅读:Spring5.1.3 @Autorwired注解原理重新回顾-CSDN博客
BeanPostProcessor#postProcessBeforeInitialization
initializeBean阶段会执行BeanPostProcessor的postProcessBeforeInitialization方法
执行自定义的BeanPostProcessor
执行CommonAnnotationBeanPostProcessor解析@PostConstruct注解
@PostConstruct public void init() { System.out.println("PostConstruct userService"); System.out.println("userDAO is not null:" + (userDAO != null)); System.out.println("appDAO is not null:" + (appDAO != null)); userServiceName = "selfUserService"; }
执行InitializingBean的afterPropertiesSet方法
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
java
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
BeanPostProcessor#postProcessAfterInitialization
InitializingBean最后阶段会执行BeanPostProcessor的postProcessAfterInitialization方法
本例
@Component public class ServiceBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // Bean 初始化前的逻辑 if (beanName.equals("userService")) { UserService userService = (UserService)bean; AppDAO appDAO = new AppDAOImpl2(); userService.setAppDAO(appDAO); System.out.println("postProcessBeforeInitialization:" + ":" + bean); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // Bean 初始化后的逻辑 if (beanName.equals("userService")) { System.out.println("postProcessAfterInitialization:" + ":" + bean); } return bean; } }