1.Spring IOC
Inverse of Control,控制反轉
簡單的說就是引入工廠(第三者),將原來在程序中手動創建的對象,交給工廠來創建管理。
1.1 理解工廠的作用
// 實現一個簡單的通過工廠獲取對象的方式
public class Factory {
//提供獲取對象的方法
public UserDAOImpl getUserDAO(){
//返回實例對象
return new UserDAOImpl ();
}
}
缺點:工廠方法仍然需要返回具體類型的實例對象,存在代碼耦合,一個工廠只能獲取單一類型的對象,
解決方案:
使用反射技術傳入具體類型的類字符串生產對象的實例:
public class Factory {
//利用反射技術生產具體類型的實例對象
public Object getBean(){
Object bean = null;
try {
//傳入類字符串,生產對象實例
bean = Class.forName("cn.itcast.spring.a_quickstart.UserDAOImpl").newInstance();
} catch (Exception e) {
e.printStackTrace();
}
//返回具體類型的對象類型實例
return bean;
}
}
public static void main(String[] args) {
//使用反射方法獲取對象
IUserDAO userDAO = (IUserDAO) userDAOFactory.getBean();
userDAO.findUserByUsernameAndPassword();
}
發現問題:類字符串是固定的,怎麼動態的傳入不同的類字符串呢?
解決方案:
使用xml配置文件動態傳入類字符串
IoC底層實現:工廠(設計模式)+反射(機制) + 配置文件(xml)。
- 工廠:spring容器
- 配置文件(xml):applicationContext.xml
- 反射:每一個bean要配置class(對象類型的類字符串)
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean: spring工廠創建的一個對象(反射機制)
id/name:對象的名字,可以用來引用或者獲取對象, 一般爲類名或接口名稱的首字母小寫
class:要創建的對象類型的類字符串,類名全路徑
-->
<bean id="userDAO" class="cn.itcast.spring.a_quickstart.UserDAOImpl" />
</beans>
public static void main(String[] args) {
//spring配置方式,創建spring工廠,加載spring配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//從spring工廠中獲取對象,通過bean的id/name
IUserDAO userDAO = (IUserDAO) ac.getBean("userDAO");
userDAO.findUserByUsernameAndPassword();
}
2.DI注入
DI:Dependency Injection 依賴注入,在Spring框架負責創建Bean對象時,動態的將依賴對象注入到Bean組件(簡單的說,可以將另外一個bean對象動態的注入到另外一個bean中。)
Di的做法是:由Spring容器創建了Service、Dao對象,並且在配置中將Dao傳入Servcie,那麼Service對象就包含了Dao對象的引用。
步驟一:將service對象和dao對象交給spring容器管理
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean: spring工廠創建的一個對象(反射機制)
id/name:對象的名字,可以用來引用或者獲取對象, 一般爲類名或接口名稱的首字母小寫
class:要創建的對象類型的類字符串,類名全路徑
-->
<bean id="userDAO" class="cn.itcast.spring.a_quickstart.UserDAOImpl" />
<bean id ="userService" class="cn.itcast.spring.a_quickstart.UserServiceImpl">
<!-- 注入對象 -->
<!-- property 根據類中的setter方法進行屬性注入 -->
<!-- name:setter方法的後綴小寫,比如setXxx 對應的name爲xxx -->
<!-- ref:引用哪一個bean(對象),值爲bean的id/name -->
<property name="userDAO" ref="userDAO" />
</bean>
</beans>
步驟二:在sevice中定義屬性提供setter方法:
public class UserServiceImpl implements IUserService{
//定義屬性
private IUserDAO userDAO;
public void setUserDAO(IUserDAO userDAO) {
this.userDAO = userDAO;
}
public void login() {
System.out.println("UserServiceImpl-service層方法調用了");
//ioc:依賴注入
userDAO.findUserByUsernameAndPassword();
}
}
步驟三:測試運行,此時獲取對象必須從spring工廠獲取(在spring容器配置中才有依賴注入,自己創建的對象沒有注入依賴關係)
public class SpringTest {
//測試
@Test
public void test(){
//創建service的示例
//IUserService userService = new UserServiceImpl();
//userService.login();
//創建spring工廠,獲取spring管理的對象
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService = (IUserService) ac.getBean("userService");
userService.login();
}
}
3.後處理Bean(BeanPostProcessor接口)
後處理Bean也稱之爲Bean的後處理器,作用是:在Bean初始化的前後,對Bean對象進行增強。它既可以增強一個指定的Bean,也可以增強所有的Bean,底層很多功能(如AOP等)的實現都是基於它的,Spring可以在容器中直接識別調用。