訓練模型過程中,經常需要追蹤一些性能指標的變化情況,以便瞭解模型的實時動態,例如:回歸任務中的MSE、分類任務中的Accuracy、生成對抗網路中的圖片、網路模型結構可視化…… 除了追蹤外,我們還希望能夠將這些指標以動態圖表的形式可視化顯示出來。 TensorFlow的附加工具Tensorboar... ...
1.Bean概述
(1) Spring IoC容器管理一個或多個bean,這些bean是根據我們所提供的配置元數據來創建的,在容器內部,BeanDefinition對象就代表了bean的配置元數據,它主要包含瞭如下幾個方面的內容:
屬性 | 說明 |
---|---|
Class | 全限定類名 |
Name | bean的名稱 |
Scope | bean的作用域 |
Constructor arguments | 構造函數參數 |
Properties | 成員變數屬性值 |
Autowiring Mode | 自動裝配模式 |
Lazy initialization mode | 懶載入模式 |
Initialization Method | 初始化回調 |
Destruction Method | 銷毀回調 |
(2) 一般情況下,Spring中的bean來自於Spring的自動掃描解析,除此之外,Spring還允許我們手動的向容器中註冊一些額外的對象,如下所示:
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("boke/definition.xml");
//1.獲取ApplicationContext中的BeanFactory
ConfigurableListableBeanFactory beanFactory = ctx.getBeanFactory();
Man man = new Man();
//2.通過beanFactory的registerSingleton方法向容器中註冊容器外的額外對象
beanFactory.registerSingleton("man", man);
//3.註冊之後,便可獲取使用該對象
Man existMan = beanFactory.getBean("man", Man.class);
existMan.doSomething();
總結一下,向Spring IOC容器中註冊額外對象,大致可分為兩步:
第一步:通過調用ApplicationContext實現類們的getBeanFactory()方法拿到DefaultListableBeanFactory
第二步:調用DefaultListableBeanFactory中的registerSingleton()方法或registerBeanDefinition()來向容器中註冊額外對象
註意:在實踐上由我們手動註冊的bean需要儘早向容器中註冊,如果註冊的太晚,就無法和Spring所提供的一些步驟結合,會導致一些依賴註入失敗
2.命名Bean
(1) Spring中的bean通常有一個唯一的id和多個別名,在基於xml的配置中,可通過bean標簽中的id屬性和name屬性來標識一個bean的id和別名,其中id屬性必須唯一,而name屬性可不唯一,多個別名之間用分號,逗號或空格分隔開,如下所示:
<!-- xml文件內容 -->
<beans ...>
<!-- 定義了一個bean,它的id為man,別名為thisMan,yesMan -->
<bean class="cn.example.spring.boke.Man" id="man" name="thisMan,yesMan"> </bean>
</beans>
//Java代碼:
ApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
//列印下麵這三個Man對象的地址,發現它們的地址相同,為同一對象
Man man = (Man) ctx.getBean("man"), thisMan = (Man) ctx.getBean("thisMan"), yesMan = (Man) ctx.getBean("yesMan");
(2) 在基於Java code的配置中,如使用@Bean,@Component等註解時,id或name屬性不是必須提供的,如果都沒有,Spring容器會預設提供一個唯一的id(生成規則:通常情況下會按照駝峰命名法取類名並將其首字母小寫,但如果類名的第一,二個字元都是大寫時,會保留原始大小寫),如下所示
//例子一:定義一個bean,未聲明它的id或name,此時Spring會自動幫我們生成一個唯一的id,為exampleA
@Component
public class ExampleA {
public void doSomething() {
System.out.println("Hello This is ExampleA");
}
}
//從Spring IOC中獲取上面這個bean
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("cn.example.spring");
//使用exampleA這個id來尋找容器中ExampleA對象
ExampleA exampleA = (ExampleA) ctx.getBean("exampleA");
exampleA.doSomething();
//例子二:定義了一個bean,未聲明它的id或name,且該類名的第一,二個字元都是大寫,此時Spring為其生成的id為IMyService,與類名相同
@Component
public class IMyService {
}
//驗證過程省略...
(3) 還可以使用alias標簽來定義一個bean的別名,如下
<beans ...>
<bean class="cn.example.spring.boke.ExampleA" id="exampleA"> </bean>
<!-- 此時,既可以用exampleA來獲取到這個bean,也可以用aliasA來獲取這個bean,它倆是等價的 -->
<alias name="exampleA" alias="aliasA"></alias>
</beans>
3.實例化bean
(1) BeanDefinition在本質上就是bean的‘配方表’,容器會根據BeanDefinition中的配置信息來創建出所需要的對象供我們使用,在基於xml的配置中,通過bean標簽中的class屬性來指定要創建對象的類類型,這個bean標簽中的class屬性對應於BeanDefanition里的Class屬性
(2) 通過美元符號($)或點符號(.)來註冊靜態內部類,如下
public class Outer {
//註意:這裡是‘靜態‘內部類
public static class Inner {
public void doSomething() {
System.out.println("Here is inner");
}
}
}
<!-- xml文件配置 -->
<beans ...>
<!-- 使用$調用靜態內部類 -->
<bean class="cn.example.spring.boke.Outer$Inner" id="inner"></bean>
<!-- 使用.調用靜態內部類,與上面的等價 -->
<!-- <bean class="cn.example.spring.boke.Outer.Inner" id="inner"></bean> -->
</beans>
//使用
ApplicationContext ctx = new ClassPathXmlApplicationContext("boke/from.xml");
//獲取已註冊到容器中的靜態內部類
Outer.Inner inner = (Outer.Inner) ctx.getBean("inner");
inner.doSomething();