Spring源码知识概览

Spring知识总览

1.1 IOC

IOC是控制反转,是一种思想

DI是依赖注入,是控制翻转的一种实现

Spring的IOC容器是用来存放对象(bean)的,Spring传统的xml配置方式,容器的大致加载过程为:

  • 1、加载xml配置文件

  • 2、解析xml文件(BeanDefinitionReder接口的xml解析的实现类)

  • 3、封装BeanDefinition(对xml或者其他配置文件进行解析,拿到bean的组成信息,例如名称,方法,属性等)

  • 4、实例化配置文件中注册的bean(通过反射,通过bean定义的scop属性值例如singleton-默认方式单例,rototype,request,session,确定bean的存在方式,但是Spring中并不是直接实例化,而是通过第5点的Bean工程来管理,从而达到可扩展的目的,保证可扩展,Spring做了很多工作,这部分比较重要)

  • 5、bean存在容器中(通过反射。BeanFactory是容器根接口,AbtsratAutowireCapableBeanFactory继承自BeanFactory,DafaultListableBeanFactory继承自AbstratAutowireCapableBeanFactory。这三个类在Spring中大量出现和使用)

Spring的Bean工厂类图

从反射到bean容器,为了保证扩展性,需要做很多增强处理,增强处理的接口是BeanFactoryPostProcessor和BeanPostProcessor,这两个接口有大量的实现。PostProcessor命名常被称作增强器。可以理解为BeanPostProcessor是为了对bean信息进行增强和修改,BeanFactoryPostProcessor是对beanDefibition进行增强和修改。BeanPostProcessor有两个方法,一个前置处理方法,一个后置处理方法

例如PlaceholderConfigurerSupport的父类PropertyResourceConfigurer实现了BeanFactoryPostProcessor。那么PlaceholderConfigurerSupport可以动态修改bean的定义信息

(1)面试题:能详细描述下bean的生命周期么?(重要)

BeanFactor接口定义了Bean生命周期先后顺序,解释如下:

 * <p>Bean factory implementations should support the standard bean lifecycle interfaces
 * as far as possible. The full set of initialization methods and their standard order is:
 * <ol>
 * <li>BeanNameAware's {@code setBeanName}
 * <li>BeanClassLoaderAware's {@code setBeanClassLoader}
 * <li>BeanFactoryAware's {@code setBeanFactory}
 * <li>EnvironmentAware's {@code setEnvironment}
 * <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
 * <li>ResourceLoaderAware's {@code setResourceLoader}
 * (only applicable when running in an application context)
 * <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
 * (only applicable when running in an application context)
 * <li>MessageSourceAware's {@code setMessageSource}
 * (only applicable when running in an application context)
 * <li>ApplicationContextAware's {@code setApplicationContext}
 * (only applicable when running in an application context)
 * <li>ServletContextAware's {@code setServletContext}
 * (only applicable when running in a web application context)
 * <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
 * <li>InitializingBean's {@code afterPropertiesSet}
 * <li>a custom init-method definition
 * <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
 * </ol>

(2)面试题:Aware接口到底有什么作用?

通过一种回调的方式,可以拿到Spring的各种组件。比如我创建的A对象,原来只能拿到A对象拿到A对象相应的信息,但是我想通过A对象,拿到Spring容器的其他各种对象,那么可以借助这个借口实现。

Aware借口介绍如下,Aere有很多实现类和实现接口。

package org.springframework.beans.factory;

/**
 * A marker superinterface indicating that a bean is eligible to be notified by the
 * Spring container of a particular framework object through a callback-style method.
 * The actual method signature is determined by individual subinterfaces but should
 * typically consist of just one void-returning method that accepts a single argument.
 *
 * <p>Note that merely implementing {@link Aware} provides no default functionality.
 * Rather, processing must be done explicitly, for example in a
 * {@link org.springframework.beans.factory.config.BeanPostProcessor}.
 * Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
 * for an example of processing specific {@code *Aware} interface callbacks.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 */
public interface Aware {

}

例如我们想通过我们创建的A对象拿到beanName。那么我们可以在A的实体类上实现BeanAware接口,实现接口方法,在我们实例化A对象后,我们可以通过A实例,拿到beanNanem

import org.springframework.beans.factory.BeanNameAware;

public class A implements BeanNameAware {
    
    
    private String beanName;
    
    
    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }
    
    public String getBeanName() {
        return beanName;
    }
    
}

  • 6、我们可以通过容器的对象get我们想要的bean

容器底层是用map结构来支持的,所以我们可以通过容器get出我们想要的对象bean。Spring中大致存在(String,Object),(Class, Object),(String, ObjectFactory),(String,BeanDefinition)几种类型的map

(3)面试题:Spring内置对象和Spring普通对象有什么区别?

内置对象是Spring提前初始化的,是容器需要的对象,比如beanFactory等,并不是我们通过配置文件注册的bean。Spring普通对象是我们通过xml或者配置类注册进Spring容器的我们需要的对象。

(4)面试题:BeanFactory和FactorBean的区别?

  • 都是用来创建对象的
  • 当使用BeanFactory创建对象时,必须遵循完整的创建过程,这个过程是由Spring来管理控制的
  • 而使用FactoryBean来创建bean,只需要调用getObject就可以返回具体对象。整个对象的创建过程是由用户自己来控制的,更加灵活。不主动调用getObject,该对象并未提前创建。不遵循Bean的生命周期
import com.dtsre.dashboard.Student;
import org.springframework.beans.factory.FactoryBean;

public class StudentFactoryBeanTest implements FactoryBean<Student> {
    @Override
    public Student getObject() throws Exception {
        return new Student();
    }

    @Override
    public Class<?> getObjectType() {
        return Student.class;
    }
}

把该FactoryBean的实例StudentFactoryBeanTest注册到Spring容器中,之后通过拿到容器context,拿到StudentFactoryBeanTest(getBean(StudentFactoryBeanTest)),只有geeBean操作后,Student对象才会被创建

1.2 Spring中重要接口概览

Spring重要接口概览

posted @ 2020-11-01 18:37  x1aoda1  阅读(312)  评论(0编辑  收藏  举报