本文作者:geek,一个聪明好学的搭档
1. 简介
开发中咱们常用@Commpont,@Service,@Resource等注解或许装备xml去声明一个类,使其成为spring容器中的bean,F X [ d以下我将用从源码1 7 w视点看以AnnotationConfigApplicationContext为例看spring如何把带有注解的类生成sp? R X 9 ] = Iring中bean。
2. 示例代码
public class TestContext {
public staticF k $ 2 } void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
SingleBean singleBean = context.getBean(SingleBean.class);f C V + R
System.out.println("<=====>"+singleBean.getTestStr());
}
}
@ComponentScan("com.geek")
public class AppConfig {
}
@Component
public class SingleBean {
private String testStr = "test% 7 o F ? e . F %Str";
public String getTestStr() {
return testStr;
}
}
留意:以上代码仅需要引进spring-context依靠即可。
3. 源码分析
上面的demo在调用AnnotationConfigh = e 6 ,ApplicationContext结构函数的时分,AppConfig类会被注册到AnnotatedBeanDefinitionP P O a : 7 ~ReN y Eader,由G M F这个reader把AppConfig解释为beanDefination,然后被spring获取到要实例化的类信息,以下为bean出产的源码及其注释。(源码根据springFramework 5.1.X)
3.1 创立进口
单例bean的创l d i Z . ; k q _立的进口为DefaultListaN w ! GbleBeanFac0 + jtory.java#preInstantiateSingletons,下面源码可见创立的bean条件为非笼统,非@LazyInit注解,Scope为singleTon(默认为singleTon)。
@Override
public void preInstantiateSingletons()3 v q ` + ] throws BeansException {
if (logger.isTrab * @ $ * w +ceEnable* x B ) Dd()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterl R = D :ate over a copy to allow fox M C / D t x Q :r init methods which in turn register new bean definitions.
// While this may not be part of the reX o N Q # I = 4gular factory bootstrap, it does otherwise work fiB $ # m yne.
//所有或许需要去实例化的class(lazy,scope)
List<` R $ s M 5String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//8 f S z d Trigger iniB Z P 3 : O ]tializatU v m % p * |ion of all non-lazy singleto s Y ` x 6 { N %n beansy a T 6 y A p . K...
for (String beanName : be4 E V d - J ~ W RanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
/**
* 非笼统,非懒初始化,单例bean
*/
if (!( 4 C L | lbd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instam ; i a F @ 9nceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() !k ; 2 E= null &4 p x x g& factory insta{ v Dnceof SmartFactork U yyBean) {
isEagerInit = AccessController.doPriviK u ^ T Rleged((PrivileN N s e U H j 8 @gedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControl* f F 1 :Context());{ K d N N y (
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isE3 W magerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
//非工厂bean实例化
else {
getBean(beanName);
}
}% @ L r 0 1 ^ E
}
/**
* 实例化完成后触发完成了SmartInitiali8 y + g 6 qzingSingleton办法的bean
* 的afts i FerSingletonsInstantiated办法
*/
// Trigger post-initialization caZ 7 $ ] ^ . allbX U n + 2 = = Z ~ack for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSM P ! G 3 O 9 fingleton) {
final SmartInita g U z iialij L 0 5 5 p CzingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiate= V b A Od();
retu4 ] 3 I Lrn null;
}, getAccessControlContext());
}
else {
smartSinglQ k / 8 Oeton.afterSingletonsInstantiatedE d S O 6 (();
}
}
}
}
3.2 创立前doGe7 A M + ? w 2 DtBean代码逻辑
getBean办法进来后便是i s b , 6 W P q e直接调用doGe. X u - f T 7 w {tBean,doG@ g * %etBean执行的源码解释如下:
protected <T> T doGetBean(final String name, @NS * & j ullable final ClassU n @ m<T> requiredType,
@Nullablt U ^ A Ce final Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 获取beanName
* 1,去掉factortoryBean前缀&
* 2,带有别名的bean转化为本来姓名
*/
final String beanName = traJ E 6 ^ { D B ~ 1nsformedBeanName(name);
Object bean;
//Z v ( Eagerly check singleton cache for manually registered singletons.
/**
* 从DefaultSingletonBeanRegistry的singletonObjects
* (spring内部用来缓存单例bean的currentHashMap)查看是否存在该bean,不存在则创立
* 触及单例形式下的循环依靠处理
*/
Object sharedInstance = getSingleton(beanName);
if (sharedInstance5 4 $ 8 5 * E j != null && args) k d i d 6 V n == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleM } 2 Zton bem 9 | @ Fan h n L 6 5 4 %'" + beanName +
"' that is not fully initializeA _ x T ~d yet - a co# t B l snsequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
} 7 Z d W f z
}
/**
*获取给定bean实例的目标,如果是Fact| 8 P ; . z ` h yory Bean,
* 则可所以bean实例自身或其创立的目标。
*/
bean = getObject~ L K l M iForBeanInstance(sharedInstY 4 5 Y eance, name, beanName, null);
}
else {
// Fail if we're already creating this b7 ; )ean instag _ ] Xnce:
// We'r! } e re assembly within a circular referenceC U | R 0 U R u [.
/**
* 原型形式下的bean存在循环依靠则会抛反常
*/
if (isPrototypeCurrentlyInCreation(bean# K HName)) {
throw new BeanCurrentlyInCreationExc p E e 7 Tceptioni H y j H 5(beanName);
}
// Check if bean definition exists in this factory.
/**
* 找不到则从父容器中查找
*/
BeanFactory parentBeanF7 y ? e Q i .aK a A u S d D r uctory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nao e 3 Gmep C ` H iToLookup = originalBeanName(name);
if (parenti X G & ^ s | ( ;BeanFactory instanceofx X | AbstractBeanFactory) {
rK R @ C 1eturn ((AbstractBeanFactory) parentBe% _ CanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);2 s m 8 t d
}
else if (args != null) {
// Delegation to parentD S l ; 8 o N m - with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> dele8 r dgate to standJ y f F o 5 @ p ard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T[ w @ k }) parentBeanFactory.getBean(nameToZ Y y N bLookup);
}
}
if (!typed l = ,CheckO4 Z Z z | U & znly) {
markBeanAsCreated(bU { beanName);
}
try {
/**
* 父容器中也找不到该bean,则需要从头实例化
* 1,获取要实例化bean的beanDefinition,
* 2,查看bean的实例化需要依靠的其他bean
*/
final RootBeanDefinition mbd = getMerge9 C I * @dLocalBeanDefinition(beanNaF W ) k ome);
checkMergedBeanDefinition(mS D X ~ E 1 T _bd, beanName, args);
// Guarantee iniJ 5 / d 9 Otialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : depe| 5 : m XndsOn) {
/**
* 若给定的依靠 bean 现已注册为依靠给定的bean
*/
if (isDependent(beanName, dep)) {
throw new BeanCreationExct _ $ S e =eption(mbd.getResource/ P n 7D[ U y Z k T u vesY D 4 *cription(), beanNi J 9 Rame,
"Circular depends-on relationship between '" + beanName + "'h S D and '" + dep + "'");
}
registerDepeL Z d I =ndentBean(dep, beanName);
try {
/**
* 递归调用getBean,优先创立依靠的bean
*/
getBean(dep);
}
catch (NoSuchBeanDefinitiF F x 7onException ex) {
throw new Bm * 8 X CeanCreationException(mbd.getResourceDescriptiY [ uon(), beanName,
"'" + beanName + "' d( 2 ^ sepends on missing bean 1 / N M'" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
/**
* 经过调用DefaultSingletonBeanRegistry的getSingleton,然后调用中心办法r & ] + G p 2createBean创立
*/
sharedInstance = getSingleton(beanName, () -> {5 # U l
try {
return createBean(bed * T ^ w J =anName, mbd, args);
}
catch (Beag 9 unsException ex) {
// Explicitly remove instance from singleton cache:} $ * a & E o ; I It migV T v c l ? } 8 ht have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also r] W ` emove anp S d V Hy beans that received a temporary reference to t) ( +he bean.
destroySingleton(beanName); a # V k R [ 3 J
throw) 8 l 1 g U W ex;
}
});
beanu v 4 = getObjectForBeanInstance(sharedInstance, nam3 . @ [e, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -&J 4 Jgt; create a new instance.
Objec{ K K l s [ qt prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeIf { M nnstance = createBean(beanName,U V T r x mbd, args);
}
finally {
afterPrototypeCreation(beanNa1 @ v yme);
}
bean = getObjectForBeanInstance(prototypeInstance_ s ! p j & j, name, beanNamez a * k , mbd);
}
else {
String scopeName = mbd.getScY D ope( - 2 n f + b , q();
final Scope sf C y H p + #cope = this.scopes.get(scopeName);
if (scopv / E 9 $ je == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Ob9 T z @ `ject scopedI# : [ H Knstance = sc. y G t : b Kope.get(beanName, () -> {
beforePrototypeCreation(beanName);
t; d ( Zry {
return createBean(beanName, mbd, args);
}
finally {
afterPro% 8 v GtotypeCreation(beanName);
}
}X / K g);
bean = getObjectForBeanInstance(scopedInstance, name, beanName, m5 P q ~ )bd);
}
catch_ s . H 7 4 F . (IllegalStateException ex) {
thrD 0 # A 8 T `ow new BeanCreat; d , % 5 T [ionExR c ] D 2 6 . ? Jception(beanName,
"Scope '" + scopeNamy P ` s ge + "' is not a9 u w p Zctive for the current thread; consider " +
"definiC E I J w R ( 2ng a scoped proxy for this bean if you intend to refer to it from a siF e 4 yngleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(bean u : O - oName);
ts ! c 5 G _ 7hrow ex;
}
}
/**
* 查看需要的bean类型是否契合
*/
// Check iw L 6 /f requir% X Ued type matches the type of the ac/ 8 ~ 9tual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanN L ( , ,otOfR4 7 K S b B A &equiredTypeException(name, requiredType, bean.gez ` . G i v C @tClass());
}
returf ? L P X 1 0 gn convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean: K v m g , '" + name + "' to required type '" +
ClassUtils.^ o e u HgetQualifiedName(requiredType) + "'", ex);
}
throw new BeanN8 y botOfRequiredTypeExc0 r A / ^ G c 6eption(name, requiredTyp8 6 9 3 j ]e, bean.getClass());
}
}
return (T) bew W S = Jan;
}
doGetBean的操作流程如下:
1,执行transformedBeanName办法转化beanName
传递的参数或许是bean的& 0 qalias或许为Fac? J x I P ytoryBean,transfo . M t * 8ormedBeanName执行的操作:(1)若传进来的FactoryBean(FactoryBean以&作为前缀符号),去掉&修饰符。(2)经n b N 5 ) ^ ? |过(1)的处理后,有alias的bean则从aliasMap中获取bean的原始beanName。
2,从容器的缓存中获取bean
getSingleton先从spring三级缓存中的榜首级singletn @ V f J – w ionObjects(Map结构)中获取,若不存在,则查看该bean是否正在创立isSingletonCurrentlyInCreation(beanName)) ,正在创立的bean会从二级缓存earT Q C w RlySingletonObjec1 H Y } Nts(M% : G n ; A p {ap结构)获取。i y c | 8 L 5 5获取到缓存的bean后会调用AbstractBeanFactory#getObjectForBeanInstance转化s ; m + m P 5 | cbean的实例自身回来。由于从缓存中拿到的7 5 4 | (或许是factoryBean,所以getObjectForBeanInstance需要把是经过从缓存factoryBeanObjectCach; 7 f re获取或经过factory.getObjecT 6 Ht()取得相应的bean回来。* V i . .
3,bean实例化前查看
(1)先查看是否原型形式下的bean是否存在循环依靠,是则会抛反常。
(2)查看父类工 D #厂(parentBeanFactory)是否存在,存在则从parentBeanFactory中递归调用doGetBean。
(3)获取改bean的beanDefinition,查看该bean实例化过程中是否触及依靠了其他8 # 5 F的bean,若是则递归调用getBean,优先创立依靠的bean。(触及单例下的循环以来处理,下篇文章p z | y N s D详细介绍)。
(4)对创立bean代码加syn^ ! i e !chronized和执行beforeSingletonCreation(beanNamE V C ve)前置处理。
3.3 创立前createBean逻辑
经过前面的doGetBean的一轮查看与准备后,便在AbstractA; d F ; p G )utowireCapableBeanFactory#createBea; % /n中开端bean的创w P t d p E A $立。
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies p0 q Z V .ost-processors, etc.
* 解析指定 BeanDV + k 1 2 0 9 ? Cefiniy L ` M m + [ o htion_ Z A 的 class
* 处理 override 特点
* 实例化的前置处理
* 创立 bean
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @N # TNullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance o! P J - ff beanL 2 ` U h C x '" + beanName + "'b V v 3 C K k"S 8 G D ( ) O * ();
}
Ro4 2 / G A d O XotBeanDefinition mbdToUse = mbd;
// Make sure beam s , ? b i ! 9n c% 0 ` ^ w 0 * lass is actu2 h & ;ally resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared me* n p j D C d rrged bean definition.
/**
* 解释bean的class,看beav M 7 ; 0 ~nDefinition是否有c5 ; -lass,否则load class
*/
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resol. t / O : 1vedClass != null &R # P ) / J Q /amp;& !mbd.hasBeanClass() && mbd.getBeanClassNam v K ;e() != null) {
mbdToUs b Te = nW E Q a / D # few RootBeanDefinition(mbd);
mbdToUse.setBean, z 1 i # p - pC` # Jlass(resolvedClass), O Q I w 9;
}
/**
* 对bean不存在lookup-method 和 replace-method
* 符号其办法的ovN ) O nerloaded为false
*/
// Prepare method overrides.
try {
mb. Q K . v L C h _dToUse.prepal ( m ; 0 I ( S freMeth^ y kodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanD_ V S 2efinitionStoreException(mbdToUse.getResourceDescript( i @ion(),
beanName, "Validation of method overrides failed", ex);
}
try {
/**
* 调用完成完成BeanPostProcessor的bean后置处理生成署理目标,
* 有署理目标则直7 B $ 7 4接回来署理目标h G g !
*/
// Give BeanPostProcen E E vssors aA ) 8 b { chance to return a proxy instead of the targS , cet bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
/**
* 无需署理的beR A G r V u ban实例化
*/
Object beanInstance = doCreateBean(beanName, mbdToUse, args);1 q u : G Y N w *
if (logger.~ K FisTraceEnabled()) {
logger.trace("Finished creating instance of be$ z 3 1 b can '" + beanName + "Z Y W N ) L ['");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppeared| A # k _ { R VSingletonException ex) {
// A previously detected exception with proper bean creation context ax ? 9 Xlready,
// or illegal singleton state to be communicated up to DefaultSj I YingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResour? B p [ ` { a IceDescription(), beanNa{ A y x d f R -me, "UnexP J $ { t - ! spected exception during bean creation", ex);
}
}
createBean的操作流程如下:
1,resolveBeanClass
解释beanDefinition的class,并且保存在beanDefinition中。
2,prepare: o 1 % g H 8 ?Men 8 ! ZthodOverb c , 0 2 * 4 {rides
处理bean中的loU . 5 okup-method (在单例bean用 @Lookup注解符号的办法,注解的@ 9 * |办法回来的目标是原型)和 replace-method( 符号的办法,符号bean中A的办法被完成被别的一个完成MethodRepla5 2 8cer接口的B办法代替)。
3,resolveBeforeInstantiation
调用完成完成BeanW V x 1 uPostJ m E k h 0 IProcessor的bean后置处理生成署理目标,有署理目标则直接回来署理目标。(spring AOP则是根据此处完成)
3.4 bean的真实实例化createBeanInstance
在AbstractAutowireCapableBean V d v 0 , dFactory#createW I s 6 } [ U – _BeanInstance中,真实创立bean,源码及注释如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbdU H 3, @b ; ^ L Y y $ iNullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?Q j O U 4 S [ m> beanClass = res| N b &olveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.i+ PsNonPublicAccessAllowed()) {
throw new BeanCreationy Q O d , s JExceptP / 7 * D fion(mbd.getResourceDescript0 ; $ y 4 x $ion8 n 6 x # % 4(), beanNamed z : !,
"Bean class isn't public, and non-public access not allowd F { O !ed: " + beanClass.getName());
}
/**
* 经过供给supplier回调办法创立
*/
Supplier<?&j o 4 9 % j 8 ggt; instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainu = HFromSupplier(instanceSupplier, beanName);
}
/**
* 经过工厂办法创立 bean 实例,可所以静态工厂办法或许实例工厂
*/
if (mbd.getFax / v ~ 6ctoryMeS 0 E j !thodName() != null) {
return instantiateUsingFactoryMeti # ! 4 h 2 Z _hod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved0 i & , K _ D h = false;
booleD ~ p Oan autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumT _ V K d c f WentLock) {
/**
* 查找现已bean现已缓存解析的结构函数或许工厂办法
*/
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
/**
* 现已有缓存的结构函数或许工厂办法,直5 K z + 8 v t =接实例化
*/t A d
if (reso. Z Mlved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
}
/**
* 经过完成BeanR ) n 6 o O 8 w 5PosZ R t FtProcessor的署理类autowired的结构函S { a 0 . B & m数实例化
*/
// Candidate constructors fo- { Br autowirP 8 ) 3 Iing?
Constructor<?>[] cb . ~ L 6tors =O 0 a & X determineConsB & d C tructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null |$ { M u M {| mbd.getResolve_ # s 7 L CdAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowirJ S r { 2 r V 3eConb 7 E strucd C dtor(beanName, mbd, ctors, args);
}
/**
* 经过自身带有autowired的结构函数实例化,经过调用反射newInstanceb @ p U Z 3 完成
*/
// Preferred constructorV & s for default construction?
ctu | m r ( 6 s iors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
/**
* 无参结构函数实例化,经过调用反射new& z % S {Instance完成
*/
// No special handling: simply use no-arg constJ | S ?ructorL U ^ I f { ^ f P.
return instantiateBean(beanName, mbd);
}
由上述源码可以看出,实例化bean操作7 [ H流程如下:
1,如果存在 Supplier3 N q T R } 回调,则经过供给supplier回调办3 _ W O 2 ? &法a Y W e o y E #创立,如以下办法界说的bean:
@RunWith(SpringRunnS ! B $ m ~ Fer.class)
@SpringBootTest(c: e Olasses = Spring5Application.class)
public class Bej J g D i * 2 canRegistrationTest {
@Autowired
private GenericWebApplicationContext context;
context.registerBean(A.class, () -> new A());
}
2,如果存在工厂办法,则经过工厂办法创立 bean 实例,可所以静态工厂办法或许实例工厂,如以下办法界说的bean:
public class AFactory implements FactoryBean<A> {
@Override
public A getObject() throws Exception {
return new A();
}
@Override
public ClasB H g j t Ps<?> g- U B c ; B ?etObjectType() {
return A.class;
}
}
//或:
@Configuration
publicd T & r class BeanConfigration {
@Bean
public A a(){
return new A();
}
}
3,现已有缓存的结构函数或许工厂办法,直接V _ _ q l实例化。
4,以上三点都不存在,则使用带参结构函数与无参结构函数实例化。如以下办法界说的bean:
@Commponet
public class A{}
4.总结
spring单例bean的实例化流程大约就是这样,许多细节当地,包含循环依靠处理,bean特点填充等细节点下一` v j e J _ x章介绍。
参阅:
-
《Spring 源码深度解析》- 郝佳 -
《死磕spring源码》-chenssy