问题描述:
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是为了读入配置信息的一个基础类,目的是在DB类在初始化时,能够获取配置信息。
正确的DB类初始化方法,是将初始化代码放在一个函数里,并用注解@PostConstruct标记,PostConstruct是指在类型创建之后,才会执行,这样能够保证所有的依赖均已添加。
@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());
}
}
错误的初始化方式。如代码所示,DB类中的变量均为静态变量,之前代码将这些静态变量的初始化放在一个static block中,但会发现,静态变量的初始化,将先于spring注册bean。也就是说,当静态块执行时,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());
}
}
还有一点需要注意的是,配置信息变量需要声明为静态变量。我推敲的结果,认为用@Configuraiton注解后的类,是会被spring当做一个bean添加到容器中,因为是Configuration,会出发自动执行类的域的setter方法,这样使得static的配置信息能够得到初始化。