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中大量出現和使用)
從反射到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物件才會被建立