找到BeanClass并且加载类

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException { if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 找到需要创建 Bean 对应的 Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
.......省略与此步骤无关的代码
}

注意:上面代码中的 resolveBeanClass(mbd, beanName) 方法,就是去查找BeanClass的,下面看看 resolveBeanClass 方法的代码

@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException { try {
// 判断 BeanDefinition 中的 beanClass 属性是不是 Class 类型的
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
// 执行搜索 Bean class
return doResolveBeanClass(mbd, typesToMatch);
} ...省略catch 代码
}
}

注意代码中有一个 mbd.hasBeanClass() 的判断, 这个地方比较有迷惑性,并不是判断beanClass属性是否存在,而是判断

beanClass 属性是不是属于 Class类型的,因为在spring最开始的扫描过程中,给BeanDefiniton 中 beanClass 属性存入的是对应 BeanDefinition 的类名称,下面是 hasBeanClass() 方法的代码:

public boolean hasBeanClass() {

   // 判断 BeanDefinition 中的 beanClass 属性是不是属于 Class 的
// 因为最开始的时候存入的是 BeanDefinition 对应的类的类名
return (this.beanClass instanceof Class);
}

如果判断 beanClass 属性 是一个CLass 对象则直接返回,否则进入doResolceBeanClass(mad, typesToMatch) 方法

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
throws ClassNotFoundException { // 获取类加载器
ClassLoader beanClassLoader = getBeanClassLoader();
ClassLoader dynamicLoader = beanClassLoader;
boolean freshResolve = false; .... 省略代码 // 这里就是拿的 RootBeanDefinition 中的 beanClass属性
String className = mbd.getBeanClassName();
if (className != null) {
// 解析 spring 自己定义的表达式---没有去了解
Object evaluated = evaluateBeanDefinitionString(className, mbd);
if (!className.equals(evaluated)) {
// A dynamically resolved expression, supported as of 4.2...
if (evaluated instanceof Class) {
return (Class<?>) evaluated;
} else if (evaluated instanceof String) {
className = (String) evaluated;
freshResolve = true;
} else {
throw new IllegalStateException("Invalid class name expression result: " + evaluated);
}
}
if (freshResolve) {
// When resolving against a temporary class loader, exit early in order
// to avoid storing the resolved Class in the bean definition.
if (dynamicLoader != null) {
try {
// 加载类,当前 需要创建的 Bean 的 Class文件
return dynamicLoader.loadClass(className);
} catch (ClassNotFoundException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
}
}
}
// 内部 使用了 Class.forName() 去加载这个类:Class.forName(name, false, clToUse);
return ClassUtils.forName(className, dynamicLoader);
}
}
// 定期解析,将结果缓存在 BeanDefinition 中
// Resolve regularly, caching the result in the BeanDefinition...
return mbd.resolveBeanClass(beanClassLoader);
}

首先我们注意到方法进入时就有一个获取BeanClassLoader的方法 getBeanClassLoader(),最终该方法的代码是如下:

@Nullable
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
// 获取当前线程的类加载器,可以设置的 Thread.currentThread().setContextClassLoader();
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
// 使用当前类的加载器去加载,有可能返回空,因为 lib 下面的 jar包使用 bootstrap 类加载器去加载的
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = ClassUtils.class.getClassLoader();
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
// 获取系统的加载器
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}

就是拿到类加载器,最终就是使用当前的类加载器,去加载mbd.getBeanClassName()方法拿出来的类名称className

这样将 BeanClass 文件就已经被加载了,紧接着就是进入实例化,在实例化前,还有一个步骤就是:实例化前

实例化前

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException { ...... 省略上一步骤的代码 try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 实例化前 InstantiationAwareBeanPostProcessor 使用的是这个 BeanPostprocessor
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// 如果实例化前,由自己创建类对象则直接返回
if (bean != null) {
return bean;
}
}
// doCreateBean 执行创建bean的方法,此方法中就会去实例化对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
... 省略日志打印
return beanInstance;
..... 省略此步骤无关代码
}

这里主要关注的就是实例化前的 InstantiationAwareBeanPostProcessor 接口,接口中有三个默认的方法,这里只讨论,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 初始化前的方法

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
.... 省略另外两个方法
}

该方法的执行时机就是在实例化前,从给出的createBean方法源码中可以体现出来,这里就给了我们许多的操作空间。

resolveBeforeInstantiation(beanName, mbdToUse); 在这个方法里面就回去执行初始化前的调用:

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) {
// 在实例化前应用BeanPostProcessor
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 初始化后的 BeanPostProcessor
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

可以看到在初始化前调用之后判断了一次 返回的 bean对象是不是空,因为在初始化前方法中给传入BeanClass 对象,在此之前就已经给 beanClass 赋值过了,这里我们可以自己去创建一个对象返回,如果是这样,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。在执行实例化前这里还有一个小的知识,就是当同时存在很多的实例化前 postProcessor ,只要一直行到 postProcessBeforeInstantiation 方法返回的bean不是空的的情况下,剩下所有的 初始化前postProcessor都不会在执行了。

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
// 这里拿到的就是 InstantiationAwareBeanPostProcessor 类型的 postProcessor
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
// 因为这里是初始化前,所以在执行到 beanPostprocessor 返回有对象的时候就直接返回,不会执行后续的 InstantiationAwareBeanPostProcessor
// 如果第一个处理器就返回了 对象实例,则不会再去执行其他的 InstantiationAwareBeanPostProcessor
if (result != null) {
return result;
}
}
return null;
}

在for循环中 getBeanPostProcessorCache().instantiationAware方法拿到的就是,InstantiationAwareBeanPostProcessor类型的postProcessor,原因是:spring对postProcessor进行了分类的:

下面进入 doCreatebean() 中初始化的流程

实例化

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException { // Instantiate the bean.
// BeanWrapper:持有创建出来的Bean
BeanWrapper instanceWrapper = null;
// 判断当前的bean定义是否为单例
if (mbd.isSingleton()) {
// 有可能在本 Bean 创建之前就已经把当前 Bean 给创建出来了(比如在依赖注入过程中)
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);// 从工厂bean缓存中移除
}// 不为空则 代表为 FactoryBean 已经创建过,存在缓存中
if (instanceWrapper == null) {
/**
* 创建bean的实例,默认使用无参构造器
* 实例化但是并未初始化,就是没有给bean的属性复制
* 组建的原始对象就创建了
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
} // Allow post-processors to modify the merged bean definition.
// 允许(MergedBeanDefinitionPostProcessor)增强器修改合并的bean definition 修改BD信息
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;
}
}
...... 省略代码 ......
}

createBeanInstance(beanName, mbd, args);此方法就是去创建 bean 的实例;

此处还有一个 应用增强器 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)根据名称可以知道这是一个操作BeanDefinition的增强器,可以去修改BeanDefinition中的属性,但是注意这个的执行时机,是在 bean 实例化之后在执行的,所以说现在修改 BeanDefiniton的有些属性是无效的,比如beanClss属性,因为bean已经创建了。

此处的 PostProcessor的类型为:MergedBeanDefinitionPostProcessor

Supplier创建对象

首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 拿到bean 的 class 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());
}
// 定义bean的提供者 ,存在就使用提供者创建对象:这是一个函数式接口
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
// 存在 bean 的提供者,则直接调用 Supplier 的 get() 方法拿到对象
return obtainFromSupplier(instanceSupplier, beanName);
}
// 使用工厂方法、例如:@Bean注解放在方法上,返回值注入容器,spring 会认为这是一个工厂方法
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);
}
} // 后置处理器 SmartInstantiationAwareBeanPostProcessor 有机会决定在创建对象钱使用那个构造器 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);
}

工厂方法创建对象

方法一

如果没有设置Supplier,则检查BeanDefinition中是否设置了factoryMethod,也就是工厂方法,有两种方式可以设置factoryMethod,比如:

<bean id="userService" class="cn.baldhead.service.UserService" factory-method="createUserService" />

对应的UserService 代码

public class UserService {

	public static UserService createUserService() {
System.out.println("执行createUserService()");
UserService userService = new UserService();
return userService;
} public void test() {
System.out.println("test");
} }

方法二

<bean id="commonService" class="cn.baldhead.service.CommonService"/>
<bean id="userService1" factory-bean="commonService" factory-method="createUserService" />

Spring发现当前BeanDefinition方法设置了工厂方法后,就会区分这两种方式,然后调用工厂方法得到对象。

值得注意的是,我们通过@Bean所定义的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常类似,@Bean所注解的方法就是factoryMethod,AppConfig对象就是factoryBean。如果@Bean所所注解的方法是static的,那么对应的就是方式一。

推断构造方法

推断完构造方法后,就会使用构造方法来进行实例化了。

额外的,在推断构造方法逻辑中除开会去选择构造方法以及查找入参对象意外,会还判断是否在对应的类中是否存在使用@Lookup注解了方法。如果存在则把该方法封装为LookupOverride对象并添加到BeanDefinition中。

@Lookup注解就是方法注入,例如demo如下:

@Component
public class UserService { private OrderService orderService; public void test() {
OrderService orderService = createOrderService();
System.out.println(orderService);
} @Lookup("orderService")
public OrderService createOrderService() {
return null;
} }

在实例化时,如果判断出来当前BeanDefinition中没有LookupOverride,那就直接用构造方法反射得到一个实例对象。如果存在LookupOverride对象,也就是类中存在@Lookup注解了的方法,那就会生成一个代理对象。

BeanDefionition 的后置处理

Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工,比如:

@Component
public class BaldHeadMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor { @Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 可以手动给 beanDefinition 得ptopertyValues 添加一个属性赋值,属性名-值(bean中的属性赋值)
if ("baldHeadService".equals(beanName)) {
beanDefinition.getPropertyValues().add("orderService", new OrderService());
}
}
}

源码在--doCreateBean()

/ Allow post-processors to modify the merged bean definition.
// 允许(MergedBeanDefinitionPostProcessor)增强器修改合并的bean definition 修改BD信息
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;
}
}

在Spring源码中,AutowiredAnnotationBeanPostProcessor就是一个MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor对象的一个Map中(injectionMetadataCache)。

实例化后

AbstractAutowireCapableBeanFactory.poputlateBean()

// 设置属性注入   之前bean的状态,例如,属性赋值之前后置处理器可以提前处理些东西
// 支持字段注入 (但是在此处什么事都没做)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}

属性填充

AbstractAutowireCapableBeanFactory.populateBean()

spring的注入

​ 必须要有对应属性的set方法,type:根据参数的类型去找到对应的Bean,name:根据方法setxxx后面的一串去找到对应的 Bean ,例如当前就是用的 xxx 作为name去找

只要是set 方法 Spring 都会去调用,不管这个set方法是做什么的,都会去调用

​ BY_TYPE,BY_NAME

	// 获取所有属性的值
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;
}

自动注入

处理属性

这个步骤中,就会处理@Autowired、@Resource、@Value等注解,也是通过InstantiationAwareBeanPostProcessor.postProcessProperties()扩展点来实现的,比如我们甚至可以实现一个自己的自动注入功能,比如:

@Component
public class BaldHeadInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("baldHeadService".equals(beanName)) {
for (Field field : bean.getClass().getFields()) {
if (field.isAnnotationPresent(BaldHeadInject.class)) {
field.setAccessible(true);
try {
field.set(bean, "123");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
} return pvs;
}
}

Aware回调

AbstractAutowireCapableBeanFactory.initializeBean(..);

回调执行Aware接口

完成了属性赋值之后,Spring会执行一些回调,包括:

  1. BeanNameAware:回传beanName给bean对象。
  2. BeanClassLoaderAware:回传classLoader给bean对象。
  3. BeanFactoryAware:回传beanFactory给对象。

初始化前

初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization(),比如

@Component
public class BaldHeadBeanPostProcessor implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("baldHeadService".equals(beanName)) {
System.out.println("初始化前");
} return bean;
}
}

利用初始化前,可以对进行了依赖注入的Bean进行处理。

在Spring源码中:

  1. InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,

  2. ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:

    1. EnvironmentAware:回传环境变量
    2. EmbeddedValueResolverAware:回传占位符解析器
    3. ResourceLoaderAware:回传资源加载器
    4. ApplicationEventPublisherAware:回传事件发布器
    5. MessageSourceAware:回传国际化资源
    6. ApplicationStartupAware:回传应用其他监听对象,可忽略
    7. ApplicationContextAware:回传Spring容器ApplicationContext
  3. @PostConstruct @PreDestory 也是在初始化前这一步进行的解析,并做了一个缓存

  4. InitDestroyAnnotationBeanPostProcessor.buildLifecycleMetadata()

  5. 	private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
    return this.emptyLifecycleMetadata;
    } // 这里面就会有 @PostConstruct 的,并且初始化方法有先后执行顺序,父类的排在前面,子类的在后面
    // 父类优先执行
    List<LifecycleElement> initMethods = new ArrayList<>();
    // 这里面会有 @PreDestroy 的
    List<LifecycleElement> destroyMethods = new ArrayList<>();
    Class<?> targetClass = clazz; do {
    final List<LifecycleElement> currInitMethods = new ArrayList<>();
    final List<LifecycleElement> currDestroyMethods = new ArrayList<>(); ReflectionUtils.doWithLocalMethods(targetClass, method -> {
    if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
    LifecycleElement element = new LifecycleElement(method);
    currInitMethods.add(element);
    if (logger.isTraceEnabled()) {
    logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
    }
    }
    if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
    currDestroyMethods.add(new LifecycleElement(method));
    if (logger.isTraceEnabled()) {
    logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
    }
    }
    });
    // 父类的初始化方法在前,也就是有一个先后顺序,先执行父类的 init-method 方法
    initMethods.addAll(0, currInitMethods);
    destroyMethods.addAll(currDestroyMethods);
    targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class); return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
    new LifecycleMetadata(clazz, initMethods, destroyMethods));
    }

初始化

  1. 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
    throws Throwable {
    // 检查是否实现了 InitializingBean 接口
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
    if (logger.isTraceEnabled()) {
    logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
    }
    // 实现了 InitializingBean 接口,执行调用 afterPropertiesSet 方法
    // 使用了多态的操作方式 将 bean 转换为一个接口(initializingBean)
    ((InitializingBean) bean).afterPropertiesSet();
    } if (mbd != null && bean.getClass() != NullBean.class) {
    // 获取自定一个init-method方法
    String initMethodName = mbd.getInitMethodName();
    if (StringUtils.hasLength(initMethodName) &&
    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    !mbd.isExternallyManagedInitMethod(initMethodName)) {
    // 执行自定一个init-method方法,通过反射 method.invoke()
    invokeCustomInitMethod(beanName, bean, mbd);
    }
    }
    }
  2. 执行BeanDefinition中指定的初始化方法

    mbd.getInitMethodName()

初始化后

spring在初始化后也提供了一个扩展点,BeanPostProcessor.postProcessAfterInitialization()->例如:

@Component
public class BaldHeadBeanPostProcessor implements BeanPostProcessor { @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("baldHeadService".equals(beanName)) {
System.out.println("初始化后");
} return bean;
}
}
if (mbd == null || !mbd.isSynthetic()) { // 初始化后执行,postProcessor
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象

总结BeanPostProcessor

  1. InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
  2. 实例化
  3. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
  4. InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
  5. 自动注入
  6. InstantiationAwareBeanPostProcessor.postProcessProperties()
  7. Aware对象
  8. BeanPostProcessor.postProcessBeforeInitialization()
  9. 初始化
  10. BeanPostProcessor.postProcessAfterInitialization()

bean的销毁

目前这一块未总结

如文中又错误请指出或者联系我:tianxiang.deng@foxmail.com

浅谈spring-createBean的更多相关文章

  1. 浅谈Spring中的Quartz配置

    浅谈Spring中的Quartz配置 2009-06-26 14:04 樊凯 博客园 字号:T | T Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,下面就看看在 ...

  2. 浅谈Spring的两种配置容器

    浅谈Spring的两种配置容器 原文:https://www.jb51.net/article/126295.htm 更新时间:2017年10月20日 08:44:41   作者:黄小鱼ZZZ     ...

  3. 1.1浅谈Spring(一个叫春的框架)

    如今各种Spring框架甚嚣尘上,但是终归还是属于spring的东西.所以在这里,个人谈一谈对spring的认识,笔者觉得掌握spring原理以及spring所涉及到的设计模式对我们具有极大的帮助.我 ...

  4. 浅谈Spring MVC知识

    关于MVC框架,我相信大家都不陌生,都会说也就是模型-视图-控制器这三层的框架结构,如果你参加面试的时候考官会问:“MVC框架是什么?你说一说.”其实我们都知道这个问题还需要问的,只要你是一个开发人员 ...

  5. 浅谈Spring发展史

    1 码农的春天----------Spring来了 Spring官网 :http://www.springframework.org 关于Spring的发展起源要回溯到2002年,当时正是Java E ...

  6. 浅谈spring 声明式事物

    此处主要讲讲事物的属性. 事物属性包含了五个方面: 1.传播行为 2.隔离规则 3.回滚规则 4.事物超时 5.是否只读 一.传播行为 事务的第一个方面是传播行为(propagation behavi ...

  7. 浅谈spring security 403机制

    403就是access denied ,就是请求拒绝,因为权限不足 三种权限级别 一.无权限访问 <security:http security="none" pattern ...

  8. [SSH 3]以网上商城项目浅谈spring配置

    导读:在做ITOO项目的时候,就用到了容器+反射,从而运用了依赖注入和依赖查找.如果看过WCF端的配置文件,那么对于这个spring的配置就很容易理解.本篇博客,是对于自己做的一个小项目中所运用到的s ...

  9. 浅谈Spring(四)

    一.Spring+MyBatis整合 spring大大简化了Mybatis的开发步骤. 1.MyBatis的开发要点: mybatis-config.xml配置文件:配置与数据库的链接.mapper文 ...

  10. 浅谈Spring(三)

    一.基础Spring的标准测试 1.导入spring与junit继承的jar 2.引入注解 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfig ...

随机推荐

  1. 深度好文:Linux系统内存知识

    点击关注上方"开源Linux", 后台回复"读书",有我为您特别筛选书籍资料~ 相关阅读: 深度好文:Linux文件系统剖析 Linux 内存是后台开发人员,需 ...

  2. 电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析)

    电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析) 目录 电机噪声之谐波分析(内附simulink中FFT分析的相关参数配置与解析) 写在前面 正文 电机噪声 谐波的产生 什么 ...

  3. c# DirectoryEntry LDAPS

    参考地址:https://stackoverflow.com/questions/54987776/ldap-connection-error-the-server-is-not-operationa ...

  4. 637. Average of Levels in Binary Tree - LeetCode

    Question 637. Average of Levels in Binary Tree Solution 思路:定义一个map,层数作为key,value保存每层的元素个数和所有元素的和,遍历这 ...

  5. unity---GL实现案例

    GL C#实现 不管是画任何东西都需要Begin()和End()函数: 画线 using System.Collections; using System.Collections.Generic; u ...

  6. CentOS7 安装高版本gcc, g++, gfortran等工具

    SCL(Software Collections)是一个CentOS/RHEL Linux平台的软件多版本共存解决方案,为用户提供一种方便.安全地安装和使用应用程序和运行时环境的多个版本的方式. De ...

  7. freeswitch使用mod_shout模块播放mp3

    概述 freeswitch 在对VOIP语音通话中,可以通过playback命令播放IVR语音文件. 默认情况下,freeswitch支持wav文件,也可以直接播放VOIP中常见编解码的G711文件. ...

  8. ML第5周学习小结

    本周收获 总结一下本周学习内容: 1.学习了<深入浅出Pandas>的第五章:Pandas高级操作的两个内容 数据迭代 函数应用 我的博客链接: pandas:数据迭代.函数应用 2.&l ...

  9. 「POI2012」井 Well

    description 你要挖井,\(n\)个地面的高度可视为\(h_i\),每次操作你可以将一个\(h_i-1\),你最多可执行\(m\)次操作. 你要任选其中一个\(h_i\)挖到\(0\),问你 ...

  10. Java - happens-before

    Java - happens-before JSR-133对 happens-before 关系的定义如下: 如果一个操作 happens-before 另一个操作,那么第一个操作的执行结果将对第二个 ...