Spring Bean生命周期
1.BeanDefinition
Spring中對(duì)象皆為bean,進(jìn)而將bean的定義信息進(jìn)行抽象為BeanDefinition酌媒,將BeanDefinition作為標(biāo)準(zhǔn)進(jìn)行創(chuàng)建。一般情況下茴扁,可以通過(guò)可以通過(guò)如下的方式進(jìn)行配置:
1.1 面向資源
1.1.1 XML配置
使用BeanDefinitionReader進(jìn)行讀取資源隧魄。xml的配置一般如下所示:
<bean id="user" class="com.johar.thinkinspring.ioc.dependency.domain.User">
? ? <property name="id" value="1"/>
? ? <property name="name" value="johar"/>
</bean>
該類的解析方式如下:
public static void main(String[] args){
? ? DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
? ? XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
? ? String location = "classpath:/dependency-lookup-context.xml";
? ? int beanDefinitionCount = reader.loadBeanDefinitions(location);
? ? System.out.println("Bean定義加載的數(shù)量:" + beanDefinitionCount);
? ? lookupCollectionByType(beanFactory);
}
private static void lookupCollectionByType(BeanFactory beanFactory){
? ? if (beanFactory instanceof ListableBeanFactory){
? ? ? ? ListableBeanFactory listableBeanFactory = (ListableBeanFactory)beanFactory;
? ? ? ? Map<String, User> userMap = listableBeanFactory.getBeansOfType(User.class);
? ? ? ? System.out.println("查找所有的User集合:" + userMap);
? ? }
}
1.1.2 Properties資源配置
Properties資源使用PropertiesBeanDefinitionReader讀取資源,源碼中PropertiesBeanDefinitionReader配置實(shí)例如下:
代碼實(shí)例如下:
user.(class)=com.johar.thinkinspring.ioc.dependency.domain.User
user.id = 100
user.name = 實(shí)例
測(cè)試代碼如下:
public static void main(String[] args) {
? ? DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
? ? PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(factory);
? ? String xmlPath = "user.properties";
? ? ClassPathResource resource = new ClassPathResource(xmlPath);
? ? EncodedResource encodedResource = new EncodedResource(resource, "UTF-8");
? ? int beanNum = reader.loadBeanDefinitions(encodedResource);
? ? System.out.printf("load bean num = " + beanNum);
? ? User user = factory.getBean(User.class);
? ? System.out.println(user);
}
有個(gè)地方需要注意一下淹冰,PropertiesBeanDefinitionReader默認(rèn)安裝ASCII讀取,但是user.properties文件使用utf-8編碼巨柒。
1.2 面向注解
public class AnnotatedBeanDefinitionParseDemo {
? ? public static void main(String[] args) {
? ? ? ? DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
? ? ? ? AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(beanFactory);
? ? ? ? reader.register(AnnotatedBeanDefinitionParseDemo.class);
? ? ? ? AnnotatedBeanDefinitionParseDemo demo = beanFactory.getBean(AnnotatedBeanDefinitionParseDemo.class);
? ? ? ? System.out.println(demo);
? ? }
}
1.3 面向API
BeanDefinitionRegistry
public static void main(String[] args){
? ? BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
? ? beanDefinitionBuilder.addPropertyValue("id", 1);
? ? beanDefinitionBuilder.addPropertyValue("name", "Johar");
? ? BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
? ? GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
? ? genericBeanDefinition.setBeanClass(User.class);
? ? MutablePropertyValues propertyValues = new MutablePropertyValues();
? ? propertyValues.add("id", 1);
? ? propertyValues.add("name", "Johar");
? ? genericBeanDefinition.setPropertyValues(propertyValues);
}
2.Spring Bean生命周期
Spring Bean的生命周期主要看AbstractApplicationContext的refresh()方法樱拴。
@Override
public void refresh() throws BeansException, IllegalStateException {
? synchronized (this.startupShutdownMonitor) {
? ? ? // Prepare this context for refreshing.
? ? ? // 容器刷新前的準(zhǔn)備,設(shè)置上下文狀態(tài)洋满,獲取屬性晶乔,驗(yàn)證必要的屬性等
? ? ? prepareRefresh();
? ? ? // Tell the subclass to refresh the internal bean factory.
? ? ? // 獲取新的beanFactory,銷毀原有beanFactory牺勾、為每個(gè)bean生成BeanDefinition等
? ? ? ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
? ? ? // Prepare the bean factory for use in this context.
? ? ? // 配置標(biāo)準(zhǔn)的beanFactory正罢,設(shè)置ClassLoader,設(shè)置SpEL表達(dá)式解析器驻民,添加忽略注入的接口翻具,添加bean,添加bean后置處理器等
? ? ? prepareBeanFactory(beanFactory);
? ? ? try {
? ? ? ? // Allows post-processing of the bean factory in context subclasses.
? ? ? ? // 模板方法回还,此時(shí)裆泳,所有的beanDefinition已經(jīng)加載,但是還沒(méi)有實(shí)例化柠硕。
? ? ? ? // 允許在子類中對(duì)beanFactory進(jìn)行擴(kuò)展處理工禾。比如添加ware相關(guān)接口自動(dòng)裝配設(shè)置,添加后置處理器等仅叫,是子類擴(kuò)展prepareBeanFactory(beanFactory)的方
? ? ? ? postProcessBeanFactory(beanFactory);
? ? ? ? // Invoke factory processors registered as beans in the context.
? ? ? ? // 實(shí)例化并調(diào)用所有注冊(cè)的beanFactory后置處理器(實(shí)現(xiàn)接口BeanFactoryPostProcessor的bean帜篇,在beanFactory標(biāo)準(zhǔn)初始化之后執(zhí)行)
? ? ? ? invokeBeanFactoryPostProcessors(beanFactory);
? ? ? ? // Register bean processors that intercept bean creation.
? ? ? ? //
? ? ? ? registerBeanPostProcessors(beanFactory);
? ? ? ? // Initialize message source for this context.
? ? ? ? initMessageSource();
? ? ? ? // Initialize event multicaster for this context.
? ? ? ? initApplicationEventMulticaster();
? ? ? ? // Initialize other special beans in specific context subclasses.
? ? ? ? onRefresh();
? ? ? ? // Check for listener beans and register them.
? ? ? ? registerListeners();
? ? ? ? // Instantiate all remaining (non-lazy-init) singletons.
? ? ? ? finishBeanFactoryInitialization(beanFactory);
? ? ? ? // Last step: publish corresponding event.
? ? ? ? finishRefresh();
? ? ? }
? ? ? catch (BeansException ex) {
? ? ? ? if (logger.isWarnEnabled()) {
? ? ? ? ? ? logger.warn("Exception encountered during context initialization - " +
? ? ? ? ? ? ? ? ? "cancelling refresh attempt: " + ex);
? ? ? ? }
? ? ? ? // Destroy already created singletons to avoid dangling resources.
? ? ? ? destroyBeans();
? ? ? ? // Reset 'active' flag.
? ? ? ? cancelRefresh(ex);
? ? ? ? // Propagate exception to caller.
? ? ? ? throw ex;
? ? ? }
? ? ? finally {
? ? ? ? // Reset common introspection caches in Spring's core, since we
? ? ? ? // might not ever need metadata for singleton beans anymore...
? ? ? ? resetCommonCaches();
? ? ? }
? }
}
在finishBeanFactoryInitialization中實(shí)例化非lazy加載的bean。另外Spring中ApplicationContext中實(shí)際使用的DefaultListableBeanFactory
2.1 BeanDefinition注冊(cè)-registerBeanDefinition
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
? ? ? throws BeanDefinitionStoreException {
? Assert.hasText(beanName, "Bean name must not be empty");
? Assert.notNull(beanDefinition, "BeanDefinition must not be null");
? if (beanDefinition instanceof AbstractBeanDefinition) {
? ? ? try {
? ? ? ? ((AbstractBeanDefinition) beanDefinition).validate();
? ? ? }
? ? ? catch (BeanDefinitionValidationException ex) {
? ? ? ? throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
? ? ? ? ? ? ? "Validation of bean definition failed", ex);
? ? ? }
? }
? BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
? if (existingDefinition != null) {
? ? ? if (!isAllowBeanDefinitionOverriding()) {
? ? ? ? throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
? ? ? }
? ? ? else if (existingDefinition.getRole() < beanDefinition.getRole()) {
? ? ? ? // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
? ? ? ? if (logger.isInfoEnabled()) {
? ? ? ? ? ? logger.info("Overriding user-defined bean definition for bean '" + beanName +
? ? ? ? ? ? ? ? ? "' with a framework-generated bean definition: replacing [" +
? ? ? ? ? ? ? ? ? existingDefinition + "] with [" + beanDefinition + "]");
? ? ? ? }
? ? ? }
? ? ? else if (!beanDefinition.equals(existingDefinition)) {
? ? ? ? if (logger.isDebugEnabled()) {
? ? ? ? ? ? logger.debug("Overriding bean definition for bean '" + beanName +
? ? ? ? ? ? ? ? ? "' with a different definition: replacing [" + existingDefinition +
? ? ? ? ? ? ? ? ? "] with [" + beanDefinition + "]");
? ? ? ? }
? ? ? }
? ? ? else {
? ? ? ? if (logger.isTraceEnabled()) {
? ? ? ? ? ? logger.trace("Overriding bean definition for bean '" + beanName +
? ? ? ? ? ? ? ? ? "' with an equivalent definition: replacing [" + existingDefinition +
? ? ? ? ? ? ? ? ? "] with [" + beanDefinition + "]");
? ? ? ? }
? ? ? }
? ? ? this.beanDefinitionMap.put(beanName, beanDefinition);
? }
? else {
? ? ? if (hasBeanCreationStarted()) {
? ? ? ? // Cannot modify startup-time collection elements anymore (for stable iteration)
? ? ? ? synchronized (this.beanDefinitionMap) {
? ? ? ? ? ? this.beanDefinitionMap.put(beanName, beanDefinition);
? ? ? ? ? ? List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
? ? ? ? ? ? updatedDefinitions.addAll(this.beanDefinitionNames);
? ? ? ? ? ? updatedDefinitions.add(beanName);
? ? ? ? ? ? this.beanDefinitionNames = updatedDefinitions;
? ? ? ? ? ? removeManualSingletonName(beanName);
? ? ? ? }
? ? ? }
? ? ? else {
? ? ? ? // Still in startup registration phase
? ? ? ? this.beanDefinitionMap.put(beanName, beanDefinition);
? ? ? ? this.beanDefinitionNames.add(beanName);
? ? ? ? removeManualSingletonName(beanName);
? ? ? }
? ? ? this.frozenBeanDefinitionNames = null;
? }
? if (existingDefinition != null || containsSingleton(beanName)) {
? ? ? resetBeanDefinition(beanName);
? }
? else if (isConfigurationFrozen()) {
? ? ? clearByTypeCache();
? }
}
2.2 BeanDefinition合并-getMergedBeanDefinition
父子BeanDefinition合并诫咱,先查找父BeanFactory笙隙,最后查找本地。
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
? String beanName = transformedBeanName(name);
? // Efficiently check whether bean definition exists in this factory.
? if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
? ? ? return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
? }
? // Resolve merged bean definition locally.
? return getMergedLocalBeanDefinition(beanName);
}
2.3 Bean實(shí)例化前階段-resolveBeforeInstantition
主要是執(zhí)行InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation坎缭,若有返回竟痰,直接退出签钩。
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
? Object bean = null;
? if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
? ? ? // Make sure bean class is actually resolved at this point.
? ? ? if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
? ? ? ? Class<?> targetType = determineTargetType(beanName, mbd);
? ? ? ? if (targetType != null) {
? ? ? ? ? ? bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
? ? ? ? ? ? if (bean != null) {
? ? ? ? ? ? ? bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
? ? ? ? ? ? }
? ? ? ? }
? ? ? }
? ? ? mbd.beforeInstantiationResolved = (bean != null);
? }
? return bean;
}
try {
? // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
? Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
? if (bean != null) {
? ? ? return bean;
? }
}
catch (Throwable ex) {
? throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
? ? ? ? "BeanPostProcessor before instantiation of bean failed", ex);
}
2.4 Bean 實(shí)例化階段 - createBeanInstance
使用instantiationstrategy創(chuàng)建bean實(shí)例,instantiationstrategy包括:factory method, constructor autowiring, or simple instantiation(CglibSubclassingInstantiationStrategy)
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
? // Make sure bean class is actually resolved at this point.
? Class<?> beanClass = resolveBeanClass(mbd, beanName);
? if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
? ? ? throw new BeanCreationException(mbd.getResourceDescription(), beanName,
? ? ? ? ? ? "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
? }
? Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
? if (instanceSupplier != null) {
? ? ? return obtainFromSupplier(instanceSupplier, beanName);
? }
? if (mbd.getFactoryMethodName() != null) {
? ? ? return instantiateUsingFactoryMethod(beanName, mbd, args);
? }
? // Shortcut when re-creating the same bean...
? boolean resolved = false;
? boolean autowireNecessary = false;
? if (args == null) {
? ? ? synchronized (mbd.constructorArgumentLock) {
? ? ? ? if (mbd.resolvedConstructorOrFactoryMethod != null) {
? ? ? ? ? ? resolved = true;
? ? ? ? ? ? autowireNecessary = mbd.constructorArgumentsResolved;
? ? ? ? }
? ? ? }
? }
? if (resolved) {
? ? ? if (autowireNecessary) {
? ? ? ? return autowireConstructor(beanName, mbd, null, null);
? ? ? }
? ? ? else {
? ? ? ? return instantiateBean(beanName, mbd);
? ? ? }
? }
? // Candidate constructors for autowiring?
? Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
? if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
? ? ? ? mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
? ? ? return autowireConstructor(beanName, mbd, ctors, args);
? }
? // Preferred constructors for default construction?
? ctors = mbd.getPreferredConstructors();
? if (ctors != null) {
? ? ? return autowireConstructor(beanName, mbd, ctors, null);
? }
? // No special handling: simply use no-arg constructor.
? return instantiateBean(beanName, mbd);
}
2.5 Bean 實(shí)例化后階段 - populateBean
InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
? if (bw == null) {
? ? ? if (mbd.hasPropertyValues()) {
? ? ? ? throw new BeanCreationException(
? ? ? ? ? ? ? mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
? ? ? }
? ? ? else {
? ? ? ? // Skip property population phase for null instance.
? ? ? ? return;
? ? ? }
? }
? // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
? // state of the bean before properties are set. This can be used, for example,
? // to support styles of field injection.
? if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
? ? ? for (BeanPostProcessor bp : getBeanPostProcessors()) {
? ? ? ? if (bp instanceof InstantiationAwareBeanPostProcessor) {
? ? ? ? ? ? InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
? ? ? ? ? ? if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
? ? ? ? ? ? ? return;
? ? ? ? ? ? }
? ? ? ? }
? ? ? }
? }
? PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
? int resolvedAutowireMode = mbd.getResolvedAutowireMode();
? if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
? ? ? MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
? ? ? // Add property values based on autowire by name if applicable.
? ? ? if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
? ? ? ? autowireByName(beanName, mbd, bw, newPvs);
? ? ? }
? ? ? // Add property values based on autowire by type if applicable.
? ? ? if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
? ? ? ? autowireByType(beanName, mbd, bw, newPvs);
? ? ? }
? ? ? pvs = newPvs;
? }
? boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
? boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
? PropertyDescriptor[] filteredPds = null;
? if (hasInstAwareBpps) {
? ? ? if (pvs == null) {
? ? ? ? pvs = mbd.getPropertyValues();
? ? ? }
? ? ? for (BeanPostProcessor bp : getBeanPostProcessors()) {
? ? ? ? if (bp instanceof InstantiationAwareBeanPostProcessor) {
? ? ? ? ? ? InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
? ? ? ? ? ? PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
? ? ? ? ? ? if (pvsToUse == null) {
? ? ? ? ? ? ? if (filteredPds == null) {
? ? ? ? ? ? ? ? ? filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
? ? ? ? ? ? ? }
? ? ? ? ? ? ? pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
? ? ? ? ? ? ? if (pvsToUse == null) {
? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? pvs = pvsToUse;
? ? ? ? }
? ? ? }
? }
? if (needsDepCheck) {
? ? ? if (filteredPds == null) {
? ? ? ? filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
? ? ? }
? ? ? checkDependencies(beanName, mbd, filteredPds, pvs);
? }
? if (pvs != null) {
? ? ? applyPropertyValues(beanName, mbd, bw, pvs);
? }
}
2.6 Bean 屬性賦值前階段 - populateBean
Bean屬性值元信息PropertyValues
Spring 5.1及以上:InstantiationAwareBeanPostProcessor#postProcessProperties
Spring 1.2-5.0 InstantiationAwareBeanPostProcessor#postProcessPropertyValues
2.7 Bean 屬性賦值階段 - populateBean
AbstractAutowireCapableBeanFactory#applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
? if (pvs.isEmpty()) {
? ? ? return;
? }
? if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
? ? ? ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
? }
? MutablePropertyValues mpvs = null;
? List<PropertyValue> original;
? if (pvs instanceof MutablePropertyValues) {
? ? ? mpvs = (MutablePropertyValues) pvs;
? ? ? if (mpvs.isConverted()) {
? ? ? ? // Shortcut: use the pre-converted values as-is.
? ? ? ? try {
? ? ? ? ? ? bw.setPropertyValues(mpvs);
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? catch (BeansException ex) {
? ? ? ? ? ? throw new BeanCreationException(
? ? ? ? ? ? ? ? ? mbd.getResourceDescription(), beanName, "Error setting property values", ex);
? ? ? ? }
? ? ? }
? ? ? original = mpvs.getPropertyValueList();
? }
? else {
? ? ? original = Arrays.asList(pvs.getPropertyValues());
? }
? TypeConverter converter = getCustomTypeConverter();
? if (converter == null) {
? ? ? converter = bw;
? }
? BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
? // Create a deep copy, resolving any references for values.
? List<PropertyValue> deepCopy = new ArrayList<>(original.size());
? boolean resolveNecessary = false;
? for (PropertyValue pv : original) {
? ? ? if (pv.isConverted()) {
? ? ? ? deepCopy.add(pv);
? ? ? }
? ? ? else {
? ? ? ? String propertyName = pv.getName();
? ? ? ? Object originalValue = pv.getValue();
? ? ? ? if (originalValue == AutowiredPropertyMarker.INSTANCE) {
? ? ? ? ? ? Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
? ? ? ? ? ? if (writeMethod == null) {
? ? ? ? ? ? ? throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
? ? ? ? ? ? }
? ? ? ? ? ? originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
? ? ? ? }
? ? ? ? Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
? ? ? ? Object convertedValue = resolvedValue;
? ? ? ? boolean convertible = bw.isWritableProperty(propertyName) &&
? ? ? ? ? ? ? !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
? ? ? ? if (convertible) {
? ? ? ? ? ? convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
? ? ? ? }
? ? ? ? // Possibly store converted value in merged bean definition,
? ? ? ? // in order to avoid re-conversion for every created bean instance.
? ? ? ? if (resolvedValue == originalValue) {
? ? ? ? ? ? if (convertible) {
? ? ? ? ? ? ? pv.setConvertedValue(convertedValue);
? ? ? ? ? ? }
? ? ? ? ? ? deepCopy.add(pv);
? ? ? ? }
? ? ? ? else if (convertible && originalValue instanceof TypedStringValue &&
? ? ? ? ? ? ? !((TypedStringValue) originalValue).isDynamic() &&
? ? ? ? ? ? ? !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
? ? ? ? ? ? pv.setConvertedValue(convertedValue);
? ? ? ? ? ? deepCopy.add(pv);
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? resolveNecessary = true;
? ? ? ? ? ? deepCopy.add(new PropertyValue(pv, convertedValue));
? ? ? ? }
? ? ? }
? }
? if (mpvs != null && !resolveNecessary) {
? ? ? mpvs.setConverted();
? }
? // Set our (possibly massaged) deep copy.
? try {
? ? ? bw.setPropertyValues(new MutablePropertyValues(deepCopy));
? }
? catch (BeansException ex) {
? ? ? throw new BeanCreationException(
? ? ? ? ? ? mbd.getResourceDescription(), beanName, "Error setting property values", ex);
? }
}
2.8 Bean Aware 接口回調(diào)階段 - initializeBean
AbstractAutowireCapableBeanFactory#invokeAwareMethods中依次BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
private void invokeAwareMethods(final String beanName, final 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);
? ? ? }
? }
}
ApplicationContextAwareProcessor#postProcessorBeforeInitialization依次調(diào)用了EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
? if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
? ? ? ? bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
? ? ? ? bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
? ? ? return bean;
? }
? AccessControlContext acc = null;
? if (System.getSecurityManager() != null) {
? ? ? acc = this.applicationContext.getBeanFactory().getAccessControlContext();
? }
? if (acc != null) {
? ? ? AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
? ? ? ? invokeAwareInterfaces(bean);
? ? ? ? return null;
? ? ? }, acc);
? }
? else {
? ? ? invokeAwareInterfaces(bean);
? }
? return bean;
}
2.9 Bean 初始化前階段 - initializeBean
BeanPostProcessor#postProcessBeforeInitialization
@Override
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;
}
2.10 Bean 初始化階段 - initializeBean
@PostConstruct 標(biāo)注方法
必須加上CommonAnnotationBeanPostProcessor坏快,在InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
? LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
? try {
? ? ? metadata.invokeInitMethods(bean, beanName);
? }
? catch (InvocationTargetException ex) {
? ? ? throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
? }
? catch (Throwable ex) {
? ? ? throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
? }
? re
實(shí)現(xiàn) InitializingBean 接口的 afterPropertiesSet() 方法
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);
? ? ? }
? }
}
自定義初始化方法
protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
? ? ? throws Throwable {
? String initMethodName = mbd.getInitMethodName();
? Assert.state(initMethodName != null, "No init method set");
? Method initMethod = (mbd.isNonPublicAccessAllowed() ?
? ? ? ? BeanUtils.findMethod(bean.getClass(), initMethodName) :
? ? ? ? ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
? if (initMethod == null) {
? ? ? if (mbd.isEnforceInitMethod()) {
? ? ? ? throw new BeanDefinitionValidationException("Could not find an init method named '" +
? ? ? ? ? ? ? initMethodName + "' on bean with name '" + beanName + "'");
? ? ? }
? ? ? else {
? ? ? ? if (logger.isTraceEnabled()) {
? ? ? ? ? ? logger.trace("No default init method named '" + initMethodName +
? ? ? ? ? ? ? ? ? "' found on bean with name '" + beanName + "'");
? ? ? ? }
? ? ? ? // Ignore non-existent default lifecycle methods.
? ? ? ? return;
? ? ? }
? }
? if (logger.isTraceEnabled()) {
? ? ? logger.trace("Invoking init method? '" + initMethodName + "' on bean with name '" + beanName + "'");
? }
? Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
? if (System.getSecurityManager() != null) {
? ? ? AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
? ? ? ? ReflectionUtils.makeAccessible(methodToInvoke);
? ? ? ? return null;
? ? ? });
? ? ? try {
? ? ? ? AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
? ? ? ? ? ? ? methodToInvoke.invoke(bean), getAccessControlContext());
? ? ? }
? ? ? catch (PrivilegedActionException pae) {
? ? ? ? InvocationTargetException ex = (InvocationTargetException) pae.getException();
? ? ? ? throw ex.getTargetException();
? ? ? }
? }
? else {
? ? ? try {
? ? ? ? ReflectionUtils.makeAccessible(methodToInvoke);
? ? ? ? methodToInvoke.invoke(bean);
? ? ? }
? ? ? catch (InvocationTargetException ex) {
? ? ? ? throw ex.getTargetException();
? ? ? }
? }
}
2.11 Bean 初始化后階段 - initializeBean
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;
}
2.12 Bean 初始化完成階段 - preInstantiateSingletons
SmartInitializingSingleton#afterSingletonsInstantiated
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
? // Initialize conversion service for this context.
? if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
? ? ? ? beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
? ? ? beanFactory.setConversionService(
? ? ? ? ? ? beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
? }
? // Register a default embedded value resolver if no bean post-processor
? // (such as a PropertyPlaceholderConfigurer bean) registered any before:
? // at this point, primarily for resolution in annotation attribute values.
? if (!beanFactory.hasEmbeddedValueResolver()) {
? ? ? beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
? }
? // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
? String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
? for (String weaverAwareName : weaverAwareNames) {
? ? ? getBean(weaverAwareName);
? }
? // Stop using the temporary ClassLoader for type matching.
? beanFactory.setTempClassLoader(null);
? // Allow for caching all bean definition metadata, not expecting further changes.
? beanFactory.freezeConfiguration();
? // Instantiate all remaining (non-lazy-init) singletons.
? beanFactory.preInstantiateSingletons();
}
2.13 Bean 銷毀前階段 - destroyBean
DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
在DisposableBeanAdapter#destroy中調(diào)用
public void destroy() {
? if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
? ? ? for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
? ? ? ? processor.postProcessBeforeDestruction(this.bean, this.beanName);
? ? ? }
? }
? if (this.invokeDisposableBean) {
? ? ? if (logger.isTraceEnabled()) {
? ? ? ? logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
? ? ? }
? ? ? try {
? ? ? ? if (System.getSecurityManager() != null) {
? ? ? ? ? ? AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
? ? ? ? ? ? ? ((DisposableBean) this.bean).destroy();
? ? ? ? ? ? ? return null;
? ? ? ? ? ? }, this.acc);
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? ((DisposableBean) this.bean).destroy();
? ? ? ? }
? ? ? }
? ? ? catch (Throwable ex) {
? ? ? ? String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
? ? ? ? if (logger.isDebugEnabled()) {
? ? ? ? ? ? logger.warn(msg, ex);
? ? ? ? }
? ? ? ? else {
? ? ? ? ? ? logger.warn(msg + ": " + ex);
? ? ? ? }
? ? ? }
? }
? if (this.destroyMethod != null) {
? ? ? invokeCustomDestroyMethod(this.destroyMethod);
? }
? else if (this.destroyMethodName != null) {
? ? ? Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
? ? ? if (methodToInvoke != null) {
? ? ? ? invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
? ? ? }
? }
}
2.14 Bean 銷毀階段 - destroyBean
依次調(diào)用:@PreDestroy 標(biāo)注方法铅檩、實(shí)現(xiàn) DisposableBean 接口的 destroy() 方法、自定義銷毀方法