IOC是控制反轉,是一種思想web
DI是依賴注入,是控制翻轉的一種實現面試
Spring的IOC容器是用來存放對象(bean)的,Spring傳統的xml配置方式,容器的大體加載過程爲:spring
一、加載xml配置文件session
二、解析xml文件(BeanDefinitionReder接口的xml解析的實現類)app
三、封裝BeanDefinition(對xml或者其餘配置文件進行解析,拿到bean的組成信息,例如名稱,方法,屬性等)ide
四、實例化配置文件中註冊的bean(經過反射,經過bean定義的scop屬性值例如singleton-默認方式單例,rototype,request,session,肯定bean的存在方式,可是Spring中並非直接實例化,而是經過第5點的Bean工程來管理,從而達到可擴展的目的,保證可擴展,Spring作了不少工做,這部分比較重要)post
五、bean存在容器中(經過反射。BeanFactory是容器根接口,AbtsratAutowireCapableBeanFactory繼承自BeanFactory,DafaultListableBeanFactory繼承自AbstratAutowireCapableBeanFactory。這三個類在Spring中大量出現和使用)this
從反射到bean容器,爲了保證擴展性,須要作不少加強處理,加強處理的接口是BeanFactoryPostProcessor和BeanPostProcessor,這兩個接口有大量的實現。PostProcessor命名常被稱做加強器。能夠理解爲BeanPostProcessor是爲了對bean信息進行加強和修改,BeanFactoryPostProcessor是對beanDefibition進行加強和修改。BeanPostProcessor有兩個方法,一個前置處理方法,一個後置處理方法code
例如PlaceholderConfigurerSupport的父類PropertyResourceConfigurer實現了BeanFactoryPostProcessor。那麼PlaceholderConfigurerSupport能夠動態修改bean的定義信息xml
(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; } }
容器底層是用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的區別?
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對象纔會被建立