分类: Java
2023-02-13 12:15:04
作者:京东科技 韩国凯
通过本文,读者可以0源码基础的初步学习spring源码,并能够举一反三从此进入源码世界的大米!
由于是{BANNED}中国第一次阅读源码,文章之中难免存在一些问题,还望包涵指正!
用一句话总结两者的区别就是: @Autowired会先通过类型注入,即byType,当存在有多个类型时会通过名称注入。@Resource则相反,会先通过名称注入,即byName,当名称不存在或有多个名称时会通过类型注入。
那么通过名称注入与通过类型注入有什么区别呢?
//创建接口 interface StuService{ String getName();
} @Service //Stu2实现接口并注册bean class Stu2 implements StuService{ @Override public String getName() { return "stu2";
}
} @Service //Stu3实现接口并注册bean class Stu3 implements StuService{ @Override public String getName() { return "stu3";
}
}
那么此时如果我们对 StuService注入, @Autowired可以选择注入的类型就有两个,分别是 Stu2与 Stu3。
需要注意的是,类型有很多种选择:
例如,我们有获取session的工具类,需要将其注入到spring之中,
@Component class SessionUtil{ public String getSession(){ return "session";
}
}
只有一个类,直接注册bean,使用时可以任意选择
@Autowired SessionUtil sessionUtil;
此时@Autowired只有一个注册类型,直接注入。
例如上述 StuService有多个实现类,每个实现类都注册了bean,因此@Autowired可以选择的类型就有两个。
@Autowired StuService stu;
根据上述的@Autowired逻辑,此时有多个类型,那么会根据bean name查找,(即类名首字母小写的),发现 stu没有对应的实现类,
此时会报错:
Field stu in com.example.demo.spring.Stu1 required a single bean, but 2 were found:
只需要将 stu 替换成 stu2或 stu3即可完成注入。
继承和其他方式同时有多个bean注入时同理。
因此,@Autowired中类型的定义可以归结为:当注册bean有多个时,类型为所有注册的bean,实现方式有:实现接口、继承、通过其他方式,例如xml配置注册bean或者@Bean注册。
@Autowired SessionUtil sessionUtil;
例如上文中 Stu1 Stu2都未指定bean名称,因此两者的bean名称分别为 stu1 stu2。
当使用@Bean在方法上注册bean,此时名称为方法名称。
@Bean() public Student getStudent(){ Student student = new Student();
student.setName("bob");
student.setId(26); return student;
}
此时该bean名称为 getStudent。
同样,我们也可以注册bean时自定义bean名称
@Bean("stu1") public Student getStudent(){ Student student = new Student();
student.setName("bob");
student.setId(26); return student;
} @Service("stu2") class Stu2 implements StuService{ @Override public String getName() { return "stu2";
}
} @Component("stu3") class Stu3 implements StuService{ @Override public String getName() { return "stu3";
}
}
在引用时指定bean:
@Resource(name = "stu2")
private StuService stu1;
当我们使用@Resource时,会根据名称也就是 stu2去查询,此时bean名称只有一个,查到返回
@Resource private Stu3 stu2;
但是在执行时却发现报错:
Bean named 'stu2' is expected to be of type 'com.example.demo.spring.Stu3' but was actually of type 'com.example.demo.spring.Stu2'
这是因为只根据了bean名称去查询,却没有根据bean类型,查到的是Stu2类型的bean,但是期望的却是Stu3,因此会发生类型不匹配。
spring的注册流程主要包含两个部分:
先了解一下几个概念:
存在于磁盘上的项目中用于描述一个bean的数据,可以是xml、properties、yaml等静态文件,也可以是各种注解描述的对应信息,例如@Service、@Component描述的一个bean的信息。
id="role" class="com.wbg.springxmlbean.entity.Role">
name="id" value="1"/>
name="roleName" value="高级工程师"/>
name="note" value="重要人员"/>
以上就是一个由xml定义的配置元数据。
在spring中,无论是那种配置元数据,{BANNED}最佳终都会转换为BeanDefinition,由BeanDefinition描述要生成并被引用的对象,可以理解为BeanDefinition就是bean的生成模板,或者是bean的说明书,按照BeanDefinition生成bean。
而将配置元数据转换为BeanDefinition的工作就是由BeanDefinitionReader完成的,对于不同的的配置元数据有不同的Reader完成对应的工作,例如有XmlBeanDefinitionReader读取xml配置信息,PropertiesBeanDefinitionReader读取properties配置信息,AnnotatedBeanDefinitionReader读取注解的配置信息。
BeanDefinitionReader的作用就是将磁盘上的文件信息或注解信息转化为内存中用于描述bean的BeanDefinition。
BeanFactoryPostProcessor是容器启动阶段Spring提供的一个扩展点,主要负责对注册到BeanDefinitionRegistry中的一个个的BeanDefinition进行一定程度上的修改与替换。例如我们的配置元信息中有些可能会修改的配置信息散落到各处,不够灵活,修改相应配置的时候比较麻烦,这时我们可以使用占位符的方式来配置。例如配置Jdbc的DataSource连接的时候可以这样配置:
id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
name="maxIdle" value="${jdbc.maxIdle}">
name="maxActive" value="${jdbc.maxActive}">
name="maxWait" value="${jdbc.maxWait}">
name="minIdle" value="${jdbc.minIdle}">
name="driverClassName" value="${jdbc.driverClassName}">
name="url" value="${jdbc.url}">
name="username" value="${jdbc.username}">
name="password" value="${jdbc.password}">
BeanFactoryPostProcessor就会对注册到BeanDefinitionRegistry中的BeanDefinition做{BANNED}最佳后的修改,替换$占位符为配置文件中的真实的数据。
一个存储BeanDefinition的地方,存储方式为KV值,key为beanName,value为BeanDefinition。
容器的启动阶段相对比较简单,首先会将存在于各处的磁盘上的配置元信息由各自的Reader读取到内存之中,转换成BeanDefinition,然后注册到BeanDefinationRegistry之中,{BANNED}最佳后由BeanFactoryPostProcessor进行修改与替换。
BeanFactory与FactoryBean的名字很像,但是确实两个不同的东西。
根据命名规则来看,BeanFactory是一个Factory,也就是一个存放bean的工厂,在创建bean完成后放到其中,使用是从其中获取。
而FactoryBean则是一个bean,只不过与不同的的bean不同的是他不仅可以创建本身类型的bean,也可以类似于Factory一样创建一层有包装的新的bean。这个Bean可以返回一个新的类型的bean,在返回之前也可以对其进行加工。
@Component class FactoryBeanDemo implements FactoryBean<Student>{ @Override public Student getObject() { return new Student();
} @Override public Class> getObjectType() { return Student.class;
}
}
创建一个FactoryBean只需要实现其接口,并实现其中的两个方法。当我们获取FactoryBean时,会返回其中 getObject()方法返回的对象。而如果想要获取FactoryBean本身,只需要在bean name前加一个"&"符号即可。
@Resource() private Object factoryBeanDemo; @GetMapping("/getStu") private String getBean(){
System.out.println(factoryBeanDemo.getClass()); return stu2.getName();
}
//输出结果 class com.example.demo.domain.Student
可以看到获取到的是Student类型。
class com.example.demo.spring.FactoryBeanDemo
将获取bean名称假“&”符号:
@Resource(name = "&factoryBeanDemo")
private Object factoryBeanDemo;
class com.example.demo.spring.FactoryBeanDemo
可以看到获取到的对象变成了FactoryBeanDemo本身。
在容器启动阶段,已经完成了bean的注册。如果该对象是配置成懒加载的方式,那么直到我们向Spring要依赖对象实例之前,其都是以BeanDefinitionRegistry中的一个个的BeanDefinition的形式存在,也就是Spring只有在我们{BANNED}中国第一次依赖对象的时候才开启相应对象的实例化阶段。而如果我们不是选择懒加载的方式,容器启动阶段完成之后,其中有一个步骤finishBeanFactoryInitialization(),在这一步将立即启动Bean实例化阶段,通过隐式的调用所有依赖对象的getBean方法来实例化所有配置的Bean,完成类的加载。
doGetBean():获取并返回bean
doGetBean()的主要流程有两个:
protected T doGetBean(
String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
String beanName = transformedBeanName(name); Object beanInstance; // Eagerly check singleton cache for manually registered singletons. // 1、查询缓存中是否存在,存在的话直接返回 Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
} // 根据缓存中的bean获取实例,主要是检测如果是FactoryBean类型,则获取其内部的getObject()的bean。(需要先了解FactoryBean的作用) beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} //2、不存在则创建bean else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
} // Check if bean definition exists in this factory. // 2.1 尝试从父类的Factory加载bean BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) { markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") .tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
} /*
* 2.2 获取RootBeanDefinition:首先会根据beanName获取BeanDefinition,然后将BeanDefinition转换为RootBeanDefinition
* BeanDefinition 接口的实现类有很多,通过不同方式注册到 BeanDefinitionRegistry 中的 BeanDefinition 的类型可能都不太相同。
{BANNED}最佳终,在通过 BeanDefinition 来创建 bean 的实例时,通常都会调用 getMergedBeanDefinition 来获取到一个 RootBeanDefinition。
所以,RootBeanDefinition 本质上是 Spring 运行时统一的 BeanDefinition 视图。
* */ RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 2.3 初始化依赖的bean String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
} registerDependentBean(dep, beanName);
try { getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
} // Create bean instance. // 2.4 创建实例 if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try { //返回真正的bean return createBean(beanName, mbd, args);
}
catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
BeanDefinition 接口的实现类有很多,通过不同方式注册到 BeanDefinitionRegistry 中的 BeanDefinition 的类型可能都不太相同。
{BANNED}最佳终,在通过 BeanDefinition 来创建 bean 的实例时,通常都会调用 getMergedBeanDefinition 来获取到一个 RootBeanDefinition。所以,RootBeanDefinition 本质上是 Spring 运行时统一的 BeanDefinition 视图。
此处就是将各种BeanDefinition统一转换为spring能识别的RootBeanDefinition。
sharedInstance = getSingleton(beanName, () -> {
try { //返回真正的bean return createBean(beanName, mbd, args);
}
catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName);
throw ex;
}
});
从getSingleton()方法中获取创建好的对象
//获取singletonFactory返回的结果 singletonObject = singletonFactory.getObject();
getSingleton()方法中{BANNED}最佳主要的一次调用也就是从singletonFactory中获取对象,而获取对象的结果就是上面代码中传入的匿名工厂返回的结果,也就是 createBean(beanName, mbd, args)
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
} RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. // 1.解析bean class Class> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
} // Prepare method overrides. // 2.准备覆盖的方法 try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
} try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. // 3.尝试返回代理创建的Bean,这个作用就是查找bean中所有实现前置和后置处理器的接口,有没有手工创建然后返回的,代替了spring的创建bean的流程 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 { //4.真正创建bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
} return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex;
} catch (Throwable ex) { throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
创建bean主要有以下几步:
以上流程都是获取bean前的流程或获取bean的准备,doCreateBean是真正的创建并填充bean的流程(去掉了一些不重要的代码)。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) { //1.通过反射创建实例化对象,并将其放入wraaper中。wraaper可以理解为bean的包装对象,里面是bean实例的,还有一些其他bean的属性方便使用 instanceWrapper = createBeanInstance(beanName, mbd, args);
} Object bean = instanceWrapper.getWrappedInstance();
Class> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
} // Allow post-processors to modify the merged bean definition. //2.允许后处理处理器修改合并后的bean定义,这里只是解析这些@Autowired @Value @Resource @PostConstruct等这些注解,并没有发生实际属性注入的动作 synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
} // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. //3.是否需要提前曝光,用来解决循环依赖时使用 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
} addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} // Initialize the bean instance. Object exposedObject = bean; //4.将实例化完成成的bean填充属性 populateBean(beanName, mbd, instanceWrapper); //5.调用初始化方法,例如 init-method exposedObject = initializeBean(beanName, exposedObject, mbd); //6.循环依赖检查 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
}
}
} // Register bean as disposable. //7.注册bean try { registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
从上述流程中可以看到,我们创建一个bean主要有以下几个流程:
可以看到,经过以上的几个步骤,我们就获取到了一个实例bean。
其中{BANNED}最佳重要的三个方法:
总结来说,创建bean的流程就是先根据反射获取对象,然后填充对象的属性,初始化,{BANNED}最佳后将bean注册。
上文我们只粗略的讲解了创建bean的过程,并没有深入的查看源码是如何实现的,例如通过反射获取对象是怎么获取的,填充属性是如何填充的,下文将详细阐述2.2.5过程中在源码层面是如何构建的。
该方法通过反射获取实例化的空属性对象。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. //1.1解析class Class> beanClass = resolveBeanClass(mbd, beanName); //1.2确认public权限 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} //2.如果存在 Supplier 回调,则调用 obtainFromSupplier() 进行初始化,因为反射获取对象的效率比较低 Supplier> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName);
} if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args);
} // Shortcut when re-creating the same bean... boolean resolved = false;
boolean autowireNecessary = false; if (args == null) {
synchronized (mbd.constructorArgumentLock) { /*
* 3.如果args为空且方法已经被resolved,则会直接选择对应的构造方法
* mbd.resolvedConstructorOrFactoryMethod的赋值在下方【1】【2】的代码中赋值
* */ if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
} if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null);
} else { return instantiateBean(beanName, mbd);
}
} // Candidate constructors for autowiring? //4.自动装配的构造方法 Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args);
} // Preferred constructors for default construction? //5.是否有首选构造方法 ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null);
} // No special handling: simply use no-arg constructor. //6.通过默认的无参构造函数 return instantiateBean(beanName, mbd);
}
Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
Constructor>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
选择AutowiredAnnotationBeanPostProcessor实现类:
其中重要的代码已贴出:
//1.遍历所有的构造方法 for (Constructor> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
} //2.查看当前构造方法是否有@Autowired注解 MergedAnnotation> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
Class> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) { // Simply proceed, no equivalent superclass constructor found... }
}
} //3.如果有@Autowired注解 if (ann != null) { //4.如果已经有一个@Autowired注解,则说明存在多个@Autowired注解,则抛出异常 if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
} //5无参构造函数 else if (candidate.getParameterCount() == 0) { //将其设置为默认构造函数 defaultConstructor = candidate;
}
} //对上面的处理过程进行判断 //6.1先检查是否有@Autowired注解 if (!candidates.isEmpty()) { // Add default constructor to list of optional constructors, as fallback. if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
} //返回@Autowired注解的构造方法 candidateConstructors = candidates.toArray(new Constructor>[0]);
} //6.2如果只有一个有参构造函数,则返回该有参函数 else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor>[] {rawCandidates[0]};
} //6.3对于非Kotlin类只会返回null,所以这里不会进入 else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor>[] {primaryConstructor};
}
else { //6.4对于不能识别的场景会进入到这里,例如有多个构造函数但是并没有指定@Autowired注解或者没有构造函数(java会帮我们生成一个无参的构造函数),返回null candidateConstructors = new Constructor>[0];
}
2-5步会对所有的构造函数进行检查,并在检查完进行标记,并会在第6步对标记的结果进行返回,按照ifelse判断顺序主要分为以下几种情况:
在获取到需要的构造函数后,会进行标记,下次不用再次解析可以直接选用那个构造函数,即上文的第4步
我们查看代码发现,无论第4步返回什么结果,{BANNED}最佳终会执行以下两个方法:
autowireConstructor()与instantiateBean()
两者都会调用
instantiate()方法
{BANNED}最佳终都会执行以下这个方法
BeanUtils.instantiateClass(constructorToUse)
也就是如下的代码
for (int i = 0 ; i < args.length; i++) { if (args[i] == null) {
Class> parameterType = parameterTypes[i]; argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null); }
else {
argsWithDefaultValues[i] = args[i]; }
}
return ctor.newInstance(argsWithDefaultValues);
其中{BANNED}最佳重要的一句:
return ctor.newInstance(argsWithDefaultValues);
可以发现,也就是这里通过反射的方式创建了一个空属性对象,并一层层返回,直到后面的属性装配等过程,可以说这里就是bean加载过程的源头。
该方法主要解析该bean所相关的注解,例如属性有@Resource,bean中@PostConstruct注解都会被解析。
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
processor主要有两个实现类:
这里需要注意的是,该方法只是会解析并不会真正的进行注入,因为学习意义不大,并不在赘述。
//遍历所有的属性
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
//对属性进行装填
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) {
if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) {
return; }
} pvs = pvsToUse; }
其中 bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName)有几个实现方法,比较重要的是:
两者{BANNED}最佳终都会进入如下方法:
//判断要注入的是属性还是方法 if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field); //如果是属性的话则直接注入 field.set(target, getResourceToInject(target, requestingBeanName));
} else { if (checkPropertySkipping(pvs)) { return;
} try {
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method); //否则通过反射注入 method.invoke(target, getResourceToInject(target, requestingBeanName));
} catch (InvocationTargetException ex) { throw ex.getTargetException();
}
}
理解起来比较简单,判断是方法注入还是属性注入,在注入时注入的对象为:
getResourceToInject(target, requestingBeanName)
找到ResourceElement的实现方法中getResource()方法:
返回了 autowireResource(this.resourceFactory, element, requestingBeanName)
if (factory instanceof AutowireCapableBeanFactory) {
AutowireCapableBeanFactory beanFactory = (AutowireCapableBeanFactory) factory; DependencyDescriptor descriptor = element.getDependencyDescriptor(); if (this.fallbackToDefaultTypeMatch && element.isDefaultName && !factory.containsBean(name)) { autowiredBeanNames = new LinkedHashSet<>(); resource = beanFactory.resolveDependency(descriptor, requestingBeanName, autowiredBeanNames, null); if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object"); }
}
else { resource = beanFactory.resolveBeanByName(name, descriptor); autowiredBeanNames = Collections.singleton(name); }
}
else { resource = factory.getBean(name, element.lookupType); autowiredBeanNames = Collections.singleton(name); }
在这个方法中,无论是if还是else,{BANNED}最佳终都会调用
getBean(name, element.lookupType)
也就是我们bean注入的入口,这个过程很像递归,在我们创建bean时,如果发现我们有依赖的其他bean,那么就会去创建依赖的bean,如果依赖的bean还有其依赖的属性则又会去创建被依赖的属性,只到{BANNED}最佳终全部创建完成,返回一开始想要创建的bean。
在该方法中,会对已经填充过属性的bean进行初始化:
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) { //对bean的前置处理,其中@PostConstruct就在此步骤中 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try { //调用初始化方法如果bean实现了InitializingBean接口,则先执行InitializingBean接口的afterPropertiesSet方法,然后执行xml或注解设置的init-method方法。 invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) { //对bean进行后置处理,对象的代理发生在此步骤中 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
在初始化bean的时候,主要分为三个部分,分别是applyBeanPostProcessorsBeforeInitialization、invokeInitMethods、applyBeanPostProcessorsAfterInitialization,分别对应于初始化的前置处理、自定义init方法、后置处理。
applyBeanPostProcessorsBeforeInitialization、applyBeanPostProcessorsAfterInitialization两个方法的大概逻辑就是获取获取所有实现其接口的类,然后执行其中被覆盖的方法。
常用的注解执行顺序如下:
并且在代码中可以看到,前置处理与后置处理都可以改变bean。
在容器启动阶段我们讲到BeanFactoryPostProcessor,这里我们讲到BeanPostProcessor,那么BeanFactoryPostProcessor 和 BeanPostProcessor 有什么区别呢?
BeanFactoryPostProcessor存在于容器启动阶段,而BeanPostProcessor存在于对象实例化阶段,BeanFactoryPostProcessor关注对象被创建之前那些配置的修改,而BeanPostProcessor阶段关注对象已经被创建之后的功能增强,替换等操作,这样就很容易区分了。
BeanPostProcessor与BeanFactoryPostProcessor都是Spring在Bean生产过程中强有力的扩展点。Spring中著名的AOP(面向切面编程),其实就是依赖BeanPostProcessor对Bean对象功能增强的。
BeanFactoryPostProcessor主要用于解决实例化之前,对实例的属性进行拓展,而BeanPostProcessor是在实例化之后对对象做的拓展。
用简单的话描述一下,创建一个bean的过程大概包括三部分:
通过以上的步骤,就可以获得我们可以正常使用的一个bean。