前面章節:
開始學習註解
1.首先我們來修改我們的beans
<?xml version= "1.0" encoding ="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- 這裏必須寫這個才能注入成功 -->
<context:annotation-config />
<bean name="userDAO" class="com.test.dao.impl.UserDAOImpl" >
<property name= "daoId" value ="1"></ property>
</bean >
<bean id="userService" class="com.test.service.UserService" >
<!-- <property name="userDAO" bean="u"
/>修改爲下面的樣子 -->
<!--
<property name= "userDAO" ref = "userDAO" /> -->
</bean >
</beans>
2. <context:annotation-config />的作用
記住這些就是用來處理我們註解的bean
3.autowired(通過byType來注入的) 注入
public class UserService
{
private UserDAO userDAO;
public UserDAO
getUserDAO() {
return userDAO ;
}
@Autowired
public void setUserDAO(UserDAO
userDAO) {
this .userDAO =
userDAO;
}
public void addUser(User
user ){
userDAO.save(user);
};
}
最好寫在setter 上面,如果寫在 private UserDAO userDAO;上面,破換封裝性
4.@Resource(默認是byName方法來注入)注入
public class UserService
{
private UserDAO userDAO; //現在是這樣,通過配置文件來實例化
public UserDAO
getUserDAO() {
return userDAO ;
}
@Resource
public void setUserDAO(UserDAO
userDAO) {
this .userDAO =
userDAO;
}
public void addUser(User
user ){
userDAO.save(user);
};
}
推薦使用@Resource
5.component(組件)註解
在spring 中如果不想自己寫bean,也可以用組件來讓spring 爲你寫
代碼:
在userDAOImpl 上加一個組件註解
@Component
public class UserDAOImpl implements UserDAO{
private int daoId ;
public int getDaoId()
{
return daoId ;
}
public void setDaoId( int daoId)
{
this .daoId =
daoId;
}
@Override
public void save(User
u) {
System. out .println("save
user" + this. daoId);
}
}
修改beans
<? xml version= "1.0" encoding = "UTF-8"?>
< beans xmlns ="http://www.springframework.org/schema/beans"
xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:context ="http://www.springframework.org/schema/context"
xsi:schemaLocation ="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd" >
<!-- 這裏必須寫這個才能輸入成功 -->
<context:annotation-config />
<context:component-scan base-package= "com.test" />
<bean id= "userService" class ="com.test.service.UserService" >
</bean >
</ beans>
這裏只有 userService 了,沒有dao的bean了
然後我們來運行一下
結果一樣
從結果中我們發現,雖然我們沒有寫dao的bean,但是spring幫我們寫了。。。
我們這裏說一下spring的寫了的過程
首先加載beans.xml ,發現有<context:annotation-config />
<context:component-scan base-package= "com.test" />
然後spring就會去掃描我們給他定好的包base-package= "com.test"
掃描到UserDAOImpl 的時候,發現有compont組件,就會把這個組件存到容器裏面去(鍵值對的形式)key(名字)userDAOImpl(就是把首字母小寫) ,值就是實例對象,然後繼續,發現resource這個注入註解,就會按名稱把這個注入進來
如果要使用我們的名字
代碼:
@Component (value="userDao" )//這裏我們名字爲userDao
public class UserDAOImpl implements UserDAO{
private int daoId ;
public int getDaoId()
{
return daoId ;
}
public void setDaoId( int daoId)
{
this .daoId =
daoId;
}
@Override
public void save(User
u) {
System. out .println("save
user" + this. daoId);
}
}
public class UserService
{
//private UserDAO userDao=new UserDAOImpl();原來是這樣的
private UserDAO userDAO; //現在是這樣,通過配置文件來實例化
public UserDAO
getUserDAO() {
return userDAO ;
}
@Resource(name= "userDao" )//這裏注入的時候去通過名字來取實例,所以也要叫userDao
public void setUserDAO(UserDAO
userDAO) {
this .userDAO =
userDAO;
}
public void addUser(User
user ){
userDAO.save(user);
};
}
運行結果:
save user0
如果我們的給的名字不一樣,會發生什麼喃?
@Resource (name= "userDAO")//我把名字改爲大寫
我們來看下結果:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService':
我直截取了第一句,意思就是bean工廠創建錯誤,意思就是沒有這個userDao,而去創建了userDAO,所以會報這個錯誤
我覺得寫上名字好些
這裏補充一點component的知識
Spring 2.5 中除了提供 @Component 註釋外,還定義了幾個擁有特殊語義的註釋,它們分別是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,這 3 個註釋和 @Component 是等效的,但是從註釋類的命名上,很容易看出這 3 個註釋分別和持久層、業務層和控制層(Web 層)相對應。雖然目前這 3 個註釋和 @Component 相比沒有什麼新意,但 Spring 將在以後的版本中爲它們添加特殊的功能。所以,如果 Web 應用程序採用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別採用
@Repository、@Service 和 @Controller 對分層中的類進行註釋,而用 @Component 對那些比較中立的類進行註釋。
在 一個稍大的項目中,通常會有上百個組件,如果這些組件採用xml的bean定義來配置,顯然會增加配置文件的體積,查找以及維護起來也不太方便。 Spring2.5爲我們引入了組件自動掃描機制,他可以在類路徑底下尋找標註了 @Component,@Service,@Controller,@Repository註解的類,並把這些類納入進spring容器中管理。它的作用 和在xml文件中使用bean節點配置組件時一樣的。要使用自動掃描機制,我們需要打開以下配置信息:
Java代碼
1. <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
2. >
3.
4. <context:component-scan base-package=”com.eric.spring”>
5. </beans>
/*其中base-package爲需要掃描的包(含所有子包)
@Service用於標註業務層組件,
@Controller用於標註控制層組件(如struts中的action),
@Repository用於標註數據訪問組件,即DAO組件,
@Component泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註。
*/
注入方式:
把 DAO實現類注入到service實現類中,把service的接口(注意不要是service的實現類)注入到action中,注入時不要new 這個注入的類,因爲spring會自動注入,如果手動再new的話會出現錯誤,然後屬性加上@Autowired後不需要getter()和 setter()方法,Spring也會自動注入。至於更具體的內容,等對注入的方式更加熟練後會做個完整的例子上來。
註解:
在 spring的配置文件裏面只需要加上<context:annotation-config/> 和<context:component-scan base-package="需要實現注入的類所在包"/>,可以使用base-package="*"表示全部的類。
<context:component-scan base-package=”com.eric.spring”>
其中base-package爲需要掃描的包(含所有子包)
在接口前面標上@Autowired和@Qualifier註釋使得接口可以被容器注入,當接口存在兩個實現類的時候必須指定其中一個來注入,使用實現類首字母小寫的字符串來注入。
@Service服務層組件,用於標註業務層組件,表示定義一個bean,自動根據bean的類名實例化一個首寫字母爲小寫的bean,例如Chinese實例化爲chinese,如果需要自己改名字則:@Service("你自己改的bean名")。
@Controller用於標註控制層組件(如struts中的action)
@Repository持久層組件,用於標註數據訪問組件,即DAO組件
@Component泛指組件,當組件不好歸類的時候,我們可以使用這個註解進行標註。
6.那controller有什麼作用喃?它有不需要new,註解它到底爲了什麼喃?
在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把用戶請求的數據經過業務處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在SpringMVC 中提供了一個非常簡便的定義Controller 的方法,你無需繼承特定的類或實現特定的接口,只需使用@Controller 標記一個類是Controller ,然後使用@RequestMapping 和@RequestParam 等一些註解用以定義URL 請求和Controller 方法之間的映射,這樣的Controller 就能被外界訪問到。此外Controller 不會直接依賴於HttpServletRequest和HttpServletResponse 等HttpServlet 對象,它們可以通過Controller 的方法參數靈活的獲取到。
在struts中Controller:控制器的作用是從客戶端接受請求,並且選擇執行相應的業務邏輯,然後把響應結果送回到客戶端。在Struts中Controller功能由ActionServlet和ActionMapping對象構成:核心是一個Servlet類型的對象ActionServlet,它用來接受客戶端的請求。ActionServlet包括一組基於配置的ActionMapping對象,每個ActionMapping對象實現了一個請求到一個具體的Model部分中Action處理器對象之間的映射。