Spring中獲取配置文件中的值非常簡單,使用@Value("xxx"), 比如port,profile等,對於Spring對象容器管理的bean而言是這樣的。但是如果想在靜態類中獲取呢?這樣就會報錯,因為@Value是基於Spring管理的對象創建的,同理,在對象注入時,我們習慣了@Autowired。這時我們就得使用spring提供的 EnvironmentAware,
ApplicationContextAware接口來獲取元數據對象,如Environment,如下面代碼所示,當然要注入雲數據對象,還是要使用Spring的方式,創建對象。
@Component public class SpringUtil implements EnvironmentAware { private static Environment env; public static String getProperty(String key){ return env.getProperty(key); } @Override public void setEnvironment(Environment environment) { injectEnvironment(env); // 因為spring會創建這個接口的實現類的一個對象,所以實例方法調用靜態方法,只是目前這個類我們是看不到的 } public static void injectEnvironment(Environment env){ SpringUtil.env = env; // 這其實是實例方法調用靜態方法 } }
那么Spirng中有沒有一個靜態類,通過名字直接獲取對象,或者這直接new有一個對象呢?很抱歉,這不是spring的正確打開方式。有時我們會很疑惑,現ApplicationContext這種類,為什么在設計時不設計成為靜態類呢,而采用單例模式。
單例就是一種簡潔美。至於為什么使用單例而不使用靜態類,我覺得原因有二:1.單例的創建和銷毀方遍,可以在不使用時節約資源2.我們繼承的類,大多數是實例方法和實例變量(至於為甚是實例方法和實例變量,應該是很絕大多數類都要實例化,並且可能有多個對象),那么繼承的時候就是實例方法和實例變量,可以說這是面向對象編程風格在單例情況下的影響。單例的缺點可能就是生成對象的開銷,現在這已經不算什么了。
-----------------------------------------2020--------------------------------------
在我們以往的經驗中,生成對象,然后交給spring管理就ok了。但是如果業務設計到要移除對象,活着替換對象,問題怎么解決呢?可以設想一種情景,如果一個對象突然在Sprinboot中消失了,會發生什么呢?