Spring 5.x Source trip seventeen getBean Detailed three
doCreateBean
Part Before the processor may return to instantiate an object, if there is no object, you'll be doCreateBean
truly create the objects. This method is very complex, we slowly run. First, the cache will first get, if you do not get to create one instance, which is a BeanWrapper
type of packaging, then processor applyMergedBeanDefinitionPostProcessors
, if needed to resolve circular references will be added to a singleton factory, then filled property, initialization registered destruction callback before returning. In the middle of each process is very complicated, we slowly say.
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {//获取factoryBean实例缓存
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {//没有即创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();//获取原始bean
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {//不为空的bean
mbd.resolvedTargetType = beanType;
}
//处理器修改合并bean定义
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
...
}
mbd.postProcessed = true;
}
}
//暴露早期的单例,处理循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
...
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//添加一个单例工厂方法
}
//进行初始化
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
...
}
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<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException...
}
}
}
}
// Register bean as disposable.
try {//注册可销毁的bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
...
}
return exposedObject;
}
createBeanInstance create the bean instance
First get the type, then get modifiers only public
allow you to create, and then obtain an instance of a custom provider, if any, direct access to return, there is no word if there are factory method name, created by the factory method, otherwise there would Analyzing the constructor to go to find the appropriate constructor for automatic assembly, otherwise a default constructor instantiated.
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//检查是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());
}
//扩展的实例提供器,可以直接从里面获取实例
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;//标记下,防止重复创建同一个bean
boolean autowireNecessary = false;//是否需要自动装配,构造器有参数的需要
if (args == null) {//无参
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {//有解析的构造器或者工厂方法
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {//有构造参数的或者工厂方法
if (autowireNecessary) {//构造器有参数的
return autowireConstructor(beanName, mbd, null, null);
}
else {//无参的
return instantiateBean(beanName, mbd);
}
}
//从bean后置处理器中为自动装配寻找构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 找出最合适的默认构造方法
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 最后才用最简单的默认构造方法
return instantiateBean(beanName, mbd);
}
Examples provider obtainFromSupplier
This is mainly the expansion of our own, we first look inside how he did, then I would be a real friends.
Mainly from a given provider in the get()
method for obtaining bean
instance, and then packed into BeanWrapper
types, then initBeanWrapper
initialized.
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(beanName);
try {
instance = instanceSupplier.get();
}
finally {
if (outerBean != null) {//不为空还是这是老的
this.currentlyCreatedBean.set(outerBean);
}
else {//为空删除
this.currentlyCreatedBean.remove();
}
}
if (instance == null) {
instance = new NullBean();
}
BeanWrapper bw = new BeanWrapperImpl(instance);
initBeanWrapper(bw);
return bw;
}
InstanceSupplier actual extension points
InstanceSupplierBeanDefinitionRegistryPostProcessor
Create a post-processor, which registered a bean
definition and examples provided, providing a UserDaoImple2
name is userDao
to keep MyConfig
the same method names, and can be called a processor add way .
public class InstanceSupplierBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
registry.registerBeanDefinition("userDao",new RootBeanDefinition(UserDao.class, () -> {
System.out.println("UserDao自定义提供器");
return new UserDaoImple2();
}));
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
UserDaoImple2
public class UserDaoImple2 implements UserDao {
@Override
public void getUser() {
System.out.println("UserDaoImple2 getUser");
}
}
MyConfig
And the method name to the strength of the provider's bean
name, but returns UserDaoImple
type.
@Configuration
public class MyConfig {
@Bean
public UserDao userDao(){
return new UserDaoImple();
}
}
test
@Test
public void InstanceSupplierTest0() throws Exception {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(MyConfig.class);
applicationContext.addBeanFactoryPostProcessor(new InstanceSupplierBeanDefinitionRegistryPostProcessor());
applicationContext.refresh();
UserDao userDao = (UserDao)applicationContext.getBean("userDao");
System.out.println(userDao);
userDao = (UserDao)applicationContext.getBean("userDao");
System.out.println(userDao);
}
result
There's offer:
free provider of:
This is how it happened, we have the provider MyConfig
in the method does not work it? Is, in fact, is bean
defined to be covered, remember speaking in front of, configuration, the processor will MyConfig
be parsed, validated, and then load the bean
definition loading bean
defined inside, there is a isOverriddenByExistingDefinition
method, can determine whether to overwrite the existing bean
definition of because we offer self-defined at the very beginning has been registered bean definitions, so MyConfig
the userDao
time was loaded will be judged to see whether or not to overwrite, if you do not cover the direct return, so we MyConfig
in the the method of information never even registered into the bean
definition:
the main judgment code is ConfigurationClassBeanDefinitionReader
the isOverriddenByExistingDefinition
fact that there is a logic to determine, first determine the existing bean
definitions and is not bean
registered with a configuration method overloading class method, because of the same name Well, if it is then do not cover, and set up the factory method is not unique, otherwise they will be covered, if not, to see is not component scan
scanned in the bean
definition, if you want to overwrite, if not to see is not internal, if it is also covered, so that we You may cover spring
the internal processor it:
protected boolean isOverriddenByExistingDefinition(BeanMethod beanMethod, String beanName) {
if (!this.registry.containsBeanDefinition(beanName)) {
return false;
}
BeanDefinition existingBeanDef = this.registry.getBeanDefinition(beanName);
//如果是ConfigurationClassBeanDefinition类型的话,且是同一个配置类的重载方法,就保存现有
if (existingBeanDef instanceof ConfigurationClassBeanDefinition) {
ConfigurationClassBeanDefinition ccbd = (ConfigurationClassBeanDefinition) existingBeanDef;
if (ccbd.getMetadata().getClassName().equals(
beanMethod.getConfigurationClass().getMetadata().getClassName())) {
if (ccbd.getFactoryMethodMetadata().getMethodName().equals(ccbd.getFactoryMethodName())) {
ccbd.setNonUniqueFactoryMethodName(ccbd.getFactoryMethodMetadata().getMethodName());//设置工厂方法不唯一,说明有重载
}
//不覆盖
return true;
}
else {
return false;//覆盖
}
}
//如果是component scan, 覆盖现有的
if (existingBeanDef instanceof ScannedGenericBeanDefinition) {
return false;
}
//如果是框架内部的,覆盖现有的
if (existingBeanDef.getRole() > BeanDefinition.ROLE_APPLICATION) {
return false;
}
//不覆盖
return true;
}
We draw a logic diagram:
look at the spring
what happens right after the internal configuration of the default class processor changed, if changed would not have to configure the processor, MyConfig
where bean
the definition would not be a:
had say spring
really flexible, extensible good, you can even change the internal processor, you can customize the processor to handle, for example, I put the processor to initialize all the coverage, and now I have the final say initialization, this scalability really strong ah:
this is bad I play:
finally provided a method of providing an example, the registration of the way , the same principle:
@Test
public void InstanceSupplierTest0() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(MyConfig.class);
applicationContext.registerBean("userDao",UserDao.class,() -> {
System.out.println("UserDao自定义提供器");
return new UserDaoImple2();
},null);
applicationContext.refresh();
UserDao userDao = (UserDao)applicationContext.getBean("userDao");
System.out.println(userDao);
userDao = (UserDao)applicationContext.getBean("userDao");
System.out.println(userDao);
}
He wrote so many, not any talk about what seems, to continue it next time.
Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.