IOC容器启动和Bean实例化实例分析

发布时间:2022-08-12 10:30:00 作者:iii
来源:亿速云 阅读:153

IOC容器启动和Bean实例化实例分析

引言

在现代Java开发中,Spring框架无疑是最为流行的框架之一。Spring框架的核心是IOC(Inversion of Control,控制反转)容器,它负责管理应用程序中的对象(即Bean)的生命周期和依赖关系。理解IOC容器的启动过程和Bean的实例化机制,对于深入掌握Spring框架至关重要。

本文将详细分析IOC容器的启动过程以及Bean的实例化过程,并通过实例代码进行说明。我们将从Spring容器的基本概念入手,逐步深入到容器的启动流程、Bean的实例化过程、依赖注入、Bean的生命周期管理等方面。

1. Spring IOC容器概述

1.1 什么是IOC容器

IOC(Inversion of Control,控制反转)是一种设计原则,它将对象的创建、依赖关系的管理从应用程序代码中剥离出来,交由容器来管理。Spring框架中的IOC容器负责管理应用程序中的Bean,包括它们的创建、初始化、依赖注入以及销毁。

Spring IOC容器主要有两种实现:

  1. BeanFactory:这是Spring框架中最基础的IOC容器,提供了基本的依赖注入功能。
  2. ApplicationContext:这是BeanFactory的子接口,提供了更多的企业级功能,如国际化、事件传播、AOP等。

1.2 Bean的定义与配置

在Spring中,Bean是应用程序中的对象,由Spring容器管理。Bean的定义可以通过XML配置文件、Java注解或Java配置类来完成。

1.2.1 XML配置

<bean id="userService" class="com.example.UserService">
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.example.UserDao"/>

1.2.2 注解配置

@Service
public class UserService {
    @Autowired
    private UserDao userDao;
}

@Repository
public class UserDao {
}

1.2.3 Java配置类

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService(userDao());
    }

    @Bean
    public UserDao userDao() {
        return new UserDao();
    }
}

2. IOC容器的启动过程

2.1 容器启动的基本流程

Spring IOC容器的启动过程可以分为以下几个步骤:

  1. 加载配置文件:容器首先会加载配置文件(XML、注解或Java配置类),解析其中的Bean定义。
  2. 创建BeanFactory:根据配置文件中的信息,创建BeanFactory实例。
  3. 注册Bean定义:将解析得到的Bean定义注册到BeanFactory中。
  4. 初始化BeanFactory:对BeanFactory进行初始化,包括设置Bean的后置处理器、初始化单例Bean等。
  5. 实例化Bean:根据Bean定义,实例化Bean对象,并进行依赖注入。
  6. 初始化Bean:调用Bean的初始化方法(如@PostConstruct注解的方法)。
  7. 容器启动完成:容器启动完成,应用程序可以开始使用这些Bean。

2.2 容器启动的源码分析

为了更好地理解容器的启动过程,我们可以通过分析Spring的源码来深入了解。

2.2.1 加载配置文件

Spring容器启动时,首先会加载配置文件。以ClassPathXmlApplicationContext为例,其构造函数会调用refresh()方法,该方法会触发容器的启动过程。

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

2.2.2 创建BeanFactory

refresh()方法中,Spring会创建一个DefaultListableBeanFactory实例,这是Spring默认的BeanFactory实现。

protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) {
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        loadBeanDefinitions(beanFactory);
        this.beanFactory = beanFactory;
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

2.2.3 注册Bean定义

loadBeanDefinitions()方法中,Spring会解析配置文件,并将Bean定义注册到BeanFactory中。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    beanDefinitionReader.setEnvironment(this.getEnvironment());
    beanDefinitionReader.setResourceLoader(this);
    beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
    initBeanDefinitionReader(beanDefinitionReader);
    loadBeanDefinitions(beanDefinitionReader);
}

2.2.4 初始化BeanFactory

refresh()方法中,Spring会调用prepareBeanFactory()方法,对BeanFactory进行初始化。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    if (beanFactory.containsBean("loadTimeWeaver")) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
    if (!beanFactory.containsBean("environment")) {
        beanFactory.registerSingleton("environment", getEnvironment());
    }
    if (!beanFactory.containsBean("systemProperties")) {
        beanFactory.registerSingleton("systemProperties", getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsBean("systemEnvironment")) {
        beanFactory.registerSingleton("systemEnvironment", getEnvironment().getSystemEnvironment());
    }
}

2.2.5 实例化Bean

refresh()方法的最后,Spring会调用finishBeanFactoryInitialization()方法,实例化所有的单例Bean。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    if (beanFactory.containsBean("conversionService")) {
        beanFactory.setConversionService(beanFactory.getBean("conversionService", ConversionService.class));
    }
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);
    beanFactory.freezeConfiguration();
    beanFactory.preInstantiateSingletons();
}

2.2.6 初始化Bean

preInstantiateSingletons()方法中,Spring会遍历所有的单例Bean,并调用它们的初始化方法。

public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                if (bean instanceof FactoryBean) {
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    } else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            } else {
                getBean(beanName);
            }
        }
    }
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            } else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

3. Bean的实例化过程

3.1 Bean的实例化流程

Bean的实例化过程可以分为以下几个步骤:

  1. 实例化Bean对象:通过反射或工厂方法创建Bean的实例。
  2. 填充属性:将Bean的属性值注入到Bean实例中。
  3. 调用初始化方法:调用Bean的初始化方法(如@PostConstruct注解的方法)。
  4. 注册Bean:将Bean实例注册到容器中,供其他Bean使用。

3.2 Bean实例化的源码分析

3.2.1 实例化Bean对象

AbstractAutowireCapableBeanFactory类中,Spring通过createBeanInstance()方法创建Bean的实例。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
    Class<?> beanClass = resolveBeanClass(mbd, beanName);
    if (beanClass == null) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Bean class [" + mbd.getBeanClassName() + "] not found");
    }
    if (System.getSecurityManager() != null) {
        return AccessController.doPrivileged((PrivilegedAction<BeanWrapper>) () ->
                instantiateBean(beanName, mbd), getAccessControlContext());
    } else {
        return instantiateBean(beanName, mbd);
    }
}

3.2.2 填充属性

populateBean()方法中,Spring会将Bean的属性值注入到Bean实例中。

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                    "Cannot apply property values to null instance");
        } else {
            return;
        }
    }
    boolean continueWithPropertyPopulation = true;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    continueWithPropertyPopulation = false;
                    break;
                }
            }
        }
    }
    if (!continueWithPropertyPopulation) {
        return;
    }
    if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
            mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    if (hasInstAwareBpps || needsDepCheck) {
        PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        if (hasInstAwareBpps) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvs == null) {
                        return;
                    }
                }
            }
        }
        if (needsDepCheck) {
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }
    }
    if (pvs != null) {
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

3.2.3 调用初始化方法

initializeBean()方法中,Spring会调用Bean的初始化方法。

protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        invokeAwareMethods(beanName, bean);
    }
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
        invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

3.2.4 注册Bean

registerDisposableBeanIfNecessary()方法中,Spring会将Bean注册到容器中。

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        } else {
            Scope scope = this.scopes.get(mbd.getScope());
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
            }
            scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        }
    }
}

4. 依赖注入

4.1 依赖注入的方式

Spring支持以下几种依赖注入方式:

  1. 构造器注入:通过构造器参数注入依赖。
  2. Setter注入:通过Setter方法注入依赖。
  3. 字段注入:通过字段直接注入依赖(使用@Autowired注解)。

4.2 依赖注入的源码分析

4.2.1 构造器注入

autowireConstructor()方法中,Spring会通过构造器注入依赖。

protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
    return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}

4.2.2 Setter注入

autowireByType()方法中,Spring会通过Setter方法注入依赖。

”`java protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { TypeConverter converter = getCustomTypeConverter(); if (converter == null) { converter = bw; } Set autowiredBeanNames = new LinkedHashSet<>(4); String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw); for (String propertyName : propertyNames) { try { PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); if (Object.class != pd.getPropertyType()) { MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd); boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass()); DependencyDescriptor desc = new DependencyDescriptor(methodParam, eager); desc.setContainingClass(bw.getWrappedClass()); Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter); if (autowired

推荐阅读:
  1. Spring IOC怎么装配Bean
  2. 怎么在Spring中为IOC容器注入Bean

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

ioc bean

上一篇:OpenCV如何实现物体的凸包检测

下一篇:docker Compose怎么部署springboot+vue前端端分离

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》