IOC:控制反轉,控制權的轉移,應用程序本身不負責依賴對象的創建和維護,而是由外部容器負責創建和維護。
DI(依賴注入):是IOC的一種實現方式,目的是創建對象並且組裝對象之間的關係。
單元測試的方式實現:
· 導入junit-*.jar包
· 創建UnitTestBase類,完成對Spring配置文件的加載、銷燬
@Before
public void before() {
if(springXmlPath.isEmpty()) {
System.out.println("出錯");
}
try {
//創建上下文
context = new ClassPathXmlApplicationContext(springXmlPath);
context.start(); //啓動組件
}catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
/**
* @SuppressWarnings 批註允許您選擇性地取消特定代碼段
* (即,類或方法)中的警告。其中的想法是當您看到警告時,
* 您將調查它,如果您確定它不是問題,您就可以添加一個 @SuppressWarnings 批註,
* 以使您不會再看到警告
* */
@SuppressWarnings("unchecked")
protected <T extends Object>T getBean(String beanId){
return (T)context.getBean(beanId);
//<E extends SomeClass> —- 有限制類型參數
}
protected <T extends Object> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
· 所有的單元測試類都繼承自UnitTestBase,通過構造函數傳入xml路徑,通過它的gerBean方法獲取想要得到的對象
· 子類(具體執行單元測試的類)加註解:@RunWith(BlockJUnit4ClassRunner.class)
RunWith:運行器,用參數類來運行。
· 單元測試方法加註解:@ Test
· 右鍵選擇要執行的單元測試方法執行或者執行一個類的全部單元測試方法
Spring注入:是指在啓動Spring容器加載bean配置的時候,完成對變量的賦值行爲。常用兩種方式:
- 設值注入(setter):set方法爲 public void set ‘Class’(class args){}
<proerty name="dao" ref="daobean"></proerty>
name:變量名
ref:其他的bean
//設置注入,先創建變量,通過ioc給變量賦值對象
public void setDao(DAO dao) {
this.dao = dao;
}
- 構造函數注入
<constructor-arg name=".." ref="......."></constructor-arg>
name的值要與構造函數參數名一致
DAO層:數據庫的訪問
Service層:業務邏輯的處理
**
Bean
**
Bean的作用域(scope屬性):
· singleton:單例,指一個Bean容器中存在一份
· prototype:每次請求(每次使用)創建新的實例,destroy方式不生效
· request:每次http請求創建一個實例且僅在當前request內有效
· session:同上,每次http請求創建,當前session內有效
· global session:基於portlet的web中有效(portlet)定義了global session),如果是在web中,同session
Bean的生命週期:
· 初始化與銷燬(3種方法)
-實現org.springframework.beans.factory.InitializingBean接口,覆蓋afterPropertiesSet方法。
-配置init-method方法
· 銷燬
-實現org.springframework.beans.factory.DisposableBean接口,覆蓋destroy方法。
-配置destory-method
配置全局默認初始化、銷燬方法:
在beans標籤添加defualt-init-method=“init” default-destory-method=“destory”
三種方法同時存在時,實現接口的優先級最大;當有其餘兩種初始化時,默認的初始化不執行。
Bean的自動裝配(Autowiring)
在beans標籤下聲明default-autowire屬性,其值爲:
· No:不做任何操作
· byName:根據屬性名自動裝配。此選項將檢查容器並根據名字查找與屬性完全一致的bean,並將其與屬性自動裝配
· byType:如果容器中存在一個與指定屬性類型相同的bean,那麼將與該屬性自動裝配;如果存在多個該類型bean,那麼拋出異常,並指出不能使用byType方式進行自動裝配;如果沒有找到相匹配的bean,則什麼事都不發生。
· Constructor:與byType方式類似,不同之處在於它應用於構造器參數。如果容器中沒有找到與構造器參數類型一致的bean,那麼拋出異常。
**Resources:**針對於資源文件的統一接口。
所有的ApplicationContext都實現了ResourceLoader接口,擁有getResource()方法,返回一個Resource對象。
ApplicationContext context;
Resource resource = context.getResource()
Bean管理的註解實現(使用java定義bean)
@Configuration : 是一個通用註解,可以用於任何bean
@Repository : 通常用於註解DAO類,即持久層
@Service : 通常用於註解Service類,即服務層
@Controller : 通常用於Controller類,即控制層(MVC)
@Component :註解普通的POJO,將其實例化到spring容器中
在xml中的beans標籤下配置搜索類的範圍:
<context:component-scan base-package="..."></context:component-scan>
Spring可以自動檢測類並註冊Bean到ApplicationContext中。需配置相應的xml的 beans標籤以用於檢測類並註冊Bean
(使用過濾器可進行自定義掃描,過濾器用法:略)
例子:
@Component("demo")
public class Demo{
//...
}
//其中demo爲該類在xml配置文件中的 id,若無指定id,則會通過BeanNameGenerator自動生成id,通常以類名爲基礎,
且類名第一個字母小寫的字符串;也可以自定義bean命名規則,實現BeanNameGenerator接口,並一定要包含一個
無參構造函數, 並在 xml 中 beans 標籤下的 context:component-scan進行聲明。
@Scope 爲 scope(作用域)的註解
@Required:註解適用於bean屬性的setter方法(這個註解僅僅表示,受影響的bean屬性必須在配置時被填充,通過在bean定義或通過自動裝配一個明確的屬性值)
(//不常用)
@AutoWired:可以將其註解爲“傳統”的setter方法;可用於構造器或成員變量
(PS:@Autowired是由Spring BeanPostProcessor處理的,所以不能再自己的BeanPostProcessor或BeanFactoryPostProcessor類型應用這些註解,這些類型必須通過XML或者Spring的@Bean註解加載)
@Qualifier:按類型自動裝配可能多個bean實例的情況,可以使用Spring的@Qualifier註解縮小範圍(或唯一指定),也可以用於指定單獨的構造器參數或方法參數;可以用於註解集合類型變量。
//指定注入id爲“main”的bean兩種方式
· public class A{
@AutoWired
@Qualifier("main")
private B b;
}
· public class A{
private B b;
private C c;
@Autowired
public void prepare(@Qualifier("main")B b, C c){
this.b=b;
this.c=c;
}
}
@Bean:標識一個用於配置和初始化一個由SpringIoC容器管理的新對象的方法,類似於XML配置文件的bean標籤。
·通常用@Comfiguration一起使用
@Comfiguration
public class A{
@Bean
public void method(){
return new A();
}
}
//@Bean默認是單例的,@Scope可改變其作用域
//默認bean的id爲方法名,可通過name自定義id
//通過配置initMethod與destroyMethod屬性執行初始化方法與銷燬方法
**@ImportResoirce:**用於類上方註解,配置資源文件,@ImportResoirce(“xml文件路徑”)
**@Value:**從資源文件中取出key並賦值
@Value("${key}")
private A a;
注意:需在xml文件中配置<context:property-placeholder location=“資源文件路徑”/>
@Resource: 註解變量或setter方法,有一個name屬性,且默認爲被注入的bean的名稱。若沒有指定name,則從變量的名稱或者setter方法名得出
@PostConstruct: 被此註解標註的方法,將在bean初始化時運行。
@PreDestroy: 被此註解標註的方法,將在bean銷燬(結束)時運行。
使用JSR330標準註解
· 使用JSR330需要依賴javax.inject包
· 使用Maven引入方式
//maven的引入方式
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
@Inject: 等效於@Autowired,可以使用與類、屬性、方法、構造器。
@Named: 如果想使用特定名稱進行依賴注入,使用@Named(@Named與@Component是等效的)