找到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. 交换机POE技术知识大全

    公众号关注 「开源Linux」 回复「学习」,有我为您特别筛选的学习资料~ 一个典型的以太网供电系统,在配线柜里保留以太网交换机设备,用一个带电源供电集线器(Midspan HUB)给局域网的双绞线提 ...

  2. 浅谈Java-String到底是值传递还是引用传递?

    参数传递 Java 中的参数传递分为 "值传递""引用传递" 如果你学过 C/C++应该很好理解,就是所谓的 "值传递" 和 "指 ...

  3. line-height和height关系

    如图所示,line-height = font-size + 上下本行距.上下半行距总是相等.font-size居于中间.当font-size值固定时,line-height越大,半行距越大.所以当l ...

  4. OpenStack平台镜像优化

    在使用打快照方式制作镜像后,镜像的大小会变得非常大,比如一个基础的CentOS镜像大小为400M左右,但是使用打快照方式制作的镜像大小会有1个G左右,具体的大小还要根据安装的东西来实际情况实际分析. ...

  5. 修改Docker容器默认时区

    运行docker容器默认时区为0区 # 运行一个nginx服务器 docker run -d -p 80:80 --name nginx nginx # 进入容器shell docker exec - ...

  6. 好客租房25-react中的事件处理(事件对象)

    3.2事件对象 可以通过事件处理程序的参数 React中的事件对象叫做:合成事件(对象) 合成事件:兼容所有浏览器 //导入react     import React from 'react'   ...

  7. ElasticSearch7.3学习(二十七)----聚合概念(bucket和metric)及其示例

    一.两个核心概念:bucket和metric 1.1 bucket 有如下数据 city name  北京 张三  北京 李四 天津 王五 天津 赵六 天津 王麻子 划分出来两个bucket,一个是北 ...

  8. MySQL数据库和Oracle数据库的区别

    Mysql数据库 由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司.是一种中小型的关系型数据库. MySQL 数据库体积小.速度快.总体拥有成本低.开放源代码,其有着广泛的应用,一般中 ...

  9. MQ 简介

    每日一句 You must try things that may not work. And you must not let anyone define your limits because o ...

  10. MTK 平台sensor arch 介绍-scp

    架构介绍 路径:vendor/mediatek/proprietary/tinysys/scp 1.[build]编译相关 2.[driver]scp 的driver,I2C,power,eint 3 ...