問題描述:
DatabaseConfig:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "database")
public class DatabaseConfig {
private static String url;
private static String user;
private static String password;
private static String driver;
//getter
//setter
}
DatabaseConfig是為了讀入配置信息的一個(gè)基礎(chǔ)類,目的是在DB類在初始化時(shí),能夠獲取配置信息。
正確的DB類初始化方法,是將初始化代碼放在一個(gè)函數(shù)里,并用注解@PostConstruct標(biāo)記,PostConstruct是指在類型創(chuàng)建之后,才會執(zhí)行,這樣能夠保證所有的依賴均已添加。
@Configuration
@ConfigurationProperties(prefix = "database")
public class DB {
private static String url ;
private static String user ;
private static String password ;
private static String driver ;
protected static SqlConnector conn;
@PostConstruct
private static void initialize(){
System.out.println("db");
ApplicationContext context = new AnnotationConfigApplicationContext(DatabaseConfig.class);
DatabaseConfig config = context.getBean(DatabaseConfig.class);
conn = new SqlConnector(config.getUrl(), config.getUser(), config.getPassword(), config.getDriver());
}
}
錯(cuò)誤的初始化方式。如代碼所示,DB類中的變量均為靜態(tài)變量,之前代碼將這些靜態(tài)變量的初始化放在一個(gè)static block中,但會發(fā)現(xiàn),靜態(tài)變量的初始化,將先于spring注冊bean。也就是說,當(dāng)靜態(tài)塊執(zhí)行時(shí),spring尚未注入已生命的bean,即DatabaseConfig,這樣就使得Database中的變量還尚未被初始化,所以獲取的是null。
@Configuration
@ConfigurationProperties(prefix = "database")
public class DB {
private static String url ;
private static String user ;
private static String password ;
private static String driver ;
protected static SqlConnector conn;
static{
ApplicationContext context = new AnnotationConfigApplicationContext(DatabaseConfig.class);
DatabaseConfig config = context.getBean(DatabaseConfig.class);
//這種方式獲取的url等均為null
conn = new SqlConnector(config.getUrl(), config.getUser(), config.getPassword(), config.getDriver());
}
}
還有一點(diǎn)需要注意的是,配置信息變量需要聲明為靜態(tài)變量。我推敲的結(jié)果,認(rèn)為用@Configuraiton注解后的類,是會被spring當(dāng)做一個(gè)bean添加到容器中,因?yàn)槭荂onfiguration,會出發(fā)自動(dòng)執(zhí)行類的域的setter方法,這樣使得static的配置信息能夠得到初始化。