「Spring」浅谈Spring的生命周期

67 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

  1. 先得找到需要初始化的Bean
  2. 对Bean创建对象(调用构造方法)
  3. 创建对象需要对标注的属性赋值
  4. Spring对这个对象进行一些初始化操作,让他达到满足放入Spring池中的要求
  5. 放入Map这个单例池中
  6. 使用这个Bean
  7. 不用了,以后也不用了就销毁这个Bean

构造->依赖注入->初始化->使用->销毁

@Component
public class UserService{
  
  @Autowried
  public UserMapper userMapper;
  
  public void test(){
    System.out.Println("我是test")
  }
}

@ComponentScan->@Component->无参构造方法->对象实例

构造

构造:项目的启动类上面直接或间接的有@ComponentScan注解,表示要扫描包里面的@Component注解,扫描到了@Component注解。想要创建一个对象

创建对象的方法只有两种

  1. 使用类的构造方法
  2. 反射创建

所以这个地方就使用了类的默认都会有的无参构造创建了UserServicebean实例对象userService

依赖注入

对象实例->依赖注入->找这个bean实例上面加了@Autowired/xxx/xxx的注解->

依赖注入:找这个bean实例上加了@Autowried之类的一些注解。然后给这个bean实例的这个属性进行赋值。赋值来源就来源于Spring池中,先试用类进行获取,获取之后如果有多个就会再使用属性值进行获取。比如private UserService userService先去找UserService这个类,找到多个就找userService这个值对应的Bean对象

初始化

初始化:使用后处理器对这个bean进行一些设置;如果是单例将这个Bean实例对象放入Spring单例池中的Map<String,Object>中。之类的一些操作

包括一些自定义的操作,比如UserService中我想要在创建bean的时候就知道管理员的一些基本信息,也就是我有一个属性是User admin;然后这个数据需要从数据库中获取。 也就是userService默认带有一个动态的管理员信息

初始化前:@PostConstruct注解标注的方法会在初始化前进行执行,其中需要的参数会在SpringBean池中获取

初始化中:实现InitializingBean接口中的方法,可以做到在这个bean的初始化中进行执行该方法的方法体逻辑

初始化后:将AOP的切面注册到这个Bean的切点中。如果有切点,就会生成代理对象。并将这个代理对象注入到Bean池中

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        // System.getSecurityManager()安全管理:因为下面初始化bean的时候会运行一些用户自定义的一些方法(实现BeanNameAware , BeanFactoryAware, BeanClassLoaderAware接口的方法)
        // Spring并不能保证这些方法会做一些违规操作,比如(删除系统文件、重启系统等)为了防止运行恶意代码对系统产生影响,需要对运行的代码的权限进行控制,这时候就要启用Java安全管理器。
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                // 对实现了 BeanNameAware , BeanFactoryAware, BeanClassLoaderAware的Bean进行处理
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //应用Bean的后处理器在初始化前
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
        try {
            //应用初始化方法(包括自定义的初始化方法)
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
        if (mbd == null || !mbd.isSynthetic()) {
            //应用后处理器在初始化结束的时候
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
​
        return wrappedBean;
    }

处理继承了Aware接口的Bean的一些方法invokeAwareMethods

    /**
     * 处理继承Aware的bean的一些操作
     *      Aware有很多子接口,这些接口拥有一种感知能力,把你想要的对象注入到你的类中
     * 如果实现了BeanNameAware,则会有一个方法setBeanName,在方法里面可以自定义一些操作。然后这个地方就有调用这个方法。
     * 如果实现了BeanClassLoaderAware,就会调用setBeanClassLoader方法
     * 如果实现了BeanFactoryAware,就会调用setBeanFactory方法。
     * 区别在于参数不一样,具体的方法所能实现的功能也不一样
     * @param beanName
     * @param bean
     */
    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);
            }
        }
    }
​
class A implements BeanNameAware , BeanFactoryAware, BeanClassLoaderAware {
    @Override
    public void setBeanName(String name) {
    }
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    }
}

处理该工厂使用的后处理器作用在该bean上applyBeanPostProcessorsBeforeInitialization

    /**
     * 在Bean的初始化前使用Bean的后处理器
     * 遍历使用此工厂创建的 bean 的 BeanPostProcessor 列表。对该bean进行应用这些后处理器
     * @param existingBean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @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;
    }
​

按照用户自定义的规则开始初始化这个 BeaninvokeInitMethods

    /**
     * 应用用户自定义的规则进行初始化这个Bean
     * 如果自定义?
     * 1、实现InitializingBean接口的afterPropertiesSet方法
     * 2、该bean的RootBeanDefinition 中initMethod 方法
     */
    protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
        //1、判断是否实现了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 + "'");
            }
            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) {
            //获取这个Bean的初始化方法。然后去执行他的invokeCustomInitMethod方法去调用初始化方法
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.isExternallyManagedInitMethod(initMethodName)) {
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }

初始化总结:初始化的时候Spring干了几件事

1、处理实现了BeanNameAware , BeanFactoryAware, BeanClassLoaderAware的Bean的方法

2、在初始化前调用这个工厂配置的后处理器

3、调用用户自定义的初始化方法(InitializingBean接口、RootBeanDefinition 中initMethod 方法)

4、在初始化结束调用这个工厂配置的后处理器