首先做个实验。
在register注册的类中写入类似一下代码。
package com.test.com.test.App;
import com.test.dao.Dao;
import com.test.dao.IndexDao;
import com.test.dao.IndexDao1;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.*;
@ComponentScan("com.test")
//@Scope("prototype")
@Configuration
@Primary
@Import(Ctest.class)
public class Appconfig {
@Bean
public static Dao indexDao(){return new IndexDao();
}
@Bean
public Dao indexDao1(){
indexDao();
return new IndexDao1();
}
}
package com.test.dao;
public class IndexDao implements Dao {
public IndexDao() {
System.out.println("DAO");
}
@Override
public void query() {
System.out.println("DAO");
}
}
package com.test.dao;
public class IndexDao1 implements Dao {
public IndexDao1() {
System.out.println("DAO1");
}
@Override
public void query() {
System.out.println("DAO1");
}
}
首先看Appconfig类中的indexDao()方法是静态的,那么执行结果会是什么样的呢?
这里DAO打印了2遍。但如果把static关键字去掉。Appconfig的代码如下:
package com.test.com.test.App;
import com.test.dao.Dao;
import com.test.dao.IndexDao;
import com.test.dao.IndexDao1;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.*;
@ComponentScan("com.test")
//@Scope("prototype")
@Configuration
@Primary
@Import(Ctest.class)
public class Appconfig {
@Bean
public Dao indexDao(){return new IndexDao();
}
@Bean
public Dao indexDao1(){
indexDao();
return new IndexDao1();
}
}
结果如下:
这里DAO只打印了一遍。
总结上述情况:当方法中存在static的时候,会调用new方法去new对象,而并不是去bean中拿对象。反之,若被new了一次,则直接从bean中拿。
经过代码跟踪跟踪到了org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod这个方法中。
里面有段代码逻辑是这样:
if (metadata.isStatic()) {
// static @Bean method
if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
}
else {
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
}
beanDef.setUniqueFactoryMethodName(methodName);
}
这里就是判断了bean中的方法的主要逻辑。由代码可以知道:
当判断出方法是静态的就会调用setBeanClass方式再去产生对象。
当判断出方法不是静态的就会调用setFactoryBeanName方式再去产生对象。
从结果看是不同的。至于为什么要这样使用则没有深究。可以自行了解。