溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

IOC容器啟動和Bean實例化實例分析

發布時間:2022-08-12 10:30:00 來源:億速云 閱讀:156 作者:iii 欄目:開發技術

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女