經典三層框架初識(二)---Spring 2.3使用註解實現建立物件
前面我們都是xml配置檔案的形式實現bean的裝配,接下來我們介紹一下用註解實現bean的裝配.和前面的Mybatis一樣,使用註解會很方便.
首先我們介紹一下幾個註解:
@Component :用於建立物件 就等價於 <bean class=""></bean> 注意:前面我們使用xml配置檔案要獲得物件,如果bean裡面沒有id值是不能獲取的.但是這裡@Component和<bean class=""></bean>等價卻是可以建立物件的,因為它其實是將沒有定義的id預設為類的名字
@Component("id") :用於建立物件 <=> <bean id = "" class=""></bean>
下面這三個的作用和上面的@Component的作用一模一樣 都是建立物件;區分出來的目的就是為了分層的
@Controller : 表示層
@Service :業務邏輯層
@Repository :資料持久層
在固定的層使用固定的註解來建立物件就可以了.其實是可以混用的
------------------------上面註解用於建立物件,下面的用於注入值--------------------------
這裡就出現一個問題,如果用註解來代替<bean>建立物件,那如何向物件裡面注入資料呢?引數如何賦值呢?
這裡我們就用下面的註解
按照型別自動注入
以UserServiceImpl這個實現類為例,它需要一個UserDao的實現類物件傳入,這時候其實就可以在private上面@Autowired,構造和setter方法都可以不要這裡其實是spring框架會自動幫我們在整個容器中取尋找這個型別 ,找到所對應的型別.
如果找不到:不注入
找到一個:注入成功
找到多個:丟擲異常
因為一個類會有很多物件,如過找到多個會報出異常,那如何解決呢?就用下面的按照名稱注入
按照名稱注入:
每一個物件都有一個id,例如我們上面說用Component("id")來建立物件起得id名,因為這個id是唯一標識,我們用這個來區分就可以了.分為下面兩種方式:
一,組合使用:@Autowired
@Qualifier("name")
二:@Resource(name = "")
上面的name都是需要傳入的物件的id值
注意:使用註解有一個前提:必須在原理匯入jar包(4+1)的基礎上再多匯入一個spring-aop.jar包才能實現
下面我們就不使用xml檔案了,來使用註解來建立一下物件:
首先我們還是新建一個java專案,並將我們的jar包匯入(Spring核心4+1外加spring-aop.jar).然後在src下建立一個dao包,裡面有一個UserDao這個介面
package dao;
public interface UserDao {
void addUser();
void deleteUser();
}
dao包下有一個子包impl,裡面是UserDao的實現類UserDaoImpl
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("新增使用者");
}
@Override
public void deleteUser() {
System.out.println("刪除使用者");
}
}
我們需要建立一個applicationContext.xml配置檔案,按照以前,通過<bean>標籤來建立物件
<?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>......</bean>,這是以前的-->
</baens>
現在我們要使用註解來建立物件來代替xml中的<bean>,所以上面的配置檔案我們就不寫<bean>標籤了.那麼我們就可以在UserDaoImpl的類宣告上方加上@..註解即可.當然我們可以使用@Component;但是dao是資料持久層互動的,我們用@Repository("userdao")並起個名字方便獲取更好一點.新增好註釋的UserDaoImpl類如下面:這樣我們就相當於建立了資料持久層UserDaoImpl的物件,並賦予了一個id
package dao.impl;
import org.springframework.stereotype.Repository;
import dao.UserDao;
@Repository("userdao")
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("新增使用者");
}
@Override
public void deleteUser() {
System.out.println("刪除使用者");
}
}
是不是就可以了呢?我們寫個測試來測試一下
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import dao.UserDao;
import dao.impl.UserDaoImpl;
public class Test {
public static void main(String[] args) {
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = ac.getBean("userdao", UserDaoImpl.class);
dao.addUser();
}
}
結果是報出異常:說沒有userdao被定義..這是為什麼呢?
注意:這裡我們獲得容器物件是從通過ClassPathXmlApplicationContext這個類來取得上下文,然後通過上下文得到物件的.但是現在xml配置檔案中什麼都沒有,也就是說對於上線文或者對於spring容器來說,並不知道UserDaoImpl的存在.其實這裡我們缺少的東西是要告訴上下文我們的物件是註解處被建立,將它管理起來.方便我們以後獲取.那我們如何讓上下文來知道們我要建立的物件在哪來存在呢?這時候就要講我們的配置檔案啦
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--在這個上下文中,我們需要告訴它去哪裡找我們用註解建立的物件,種類需要用到名稱空間
上面xmlns="http://www.springframework.org/schema/beans"這個就是名稱空間
是一個預設的名稱空間,我們這裡需要一個context的名稱空間,那就抄一個.由於預設的就一個,這裡我們給它一個別名context;
由於預設的是beans的,所以這裡最後我們要把beans改為context
-->
<!--
名稱空間是做什麼的呢?
在schema中:通過name space 也就是名稱空間來規範標籤的;在每一個名稱空間底下都聲明瞭很多特定的標籤
我們以前之所以能用bean這個標籤是因為它在預設的名稱空間底下,所謂的beans對應的路徑下宣告著
我們現在要做的是讓spring ioc容器知道UserDaoImpl這個物件的存在,所以它需要用到是上下文的名稱空間,所以我們在上面
用xmlns:context="http://www.springframework.org/schema/context"宣告出來這個名稱空間
也就是說,把這些所有內容都包含到上下文中去
但是僅僅像上面那樣宣告是沒有標籤的,只是說要引用context,但是裡面有哪些標籤,去哪裡找還要通過xsi:schemaLocation來決定
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
將這兩句新增到上面的xsi:schemaLocation中,這樣我們就知道了context名稱空間裡面都有哪些標籤以及所代表的含義
之所以我們這樣修改,是因為spring的名稱空間和約束名字起得都特別規範,這樣我們就可以方便新增.
-->
<!--
這裡我們要用context:component-scan這個標籤
base-package:通過包的名字來進行掃描的,我們這裡要建立UserDaoImpl這個物件它在dao.impl這個包下,這裡我們就寫dao就可以了
會將dao和它子包impl包下的所有類都掃描
這是我們就可以建立了
-->
<context:component-scan base-package="dao" ></context:component-scan>
</beans>
一些重要的內容,我都隨著註釋寫在配置檔案中啦.這時候我們再來測試一下:
就成功了.這個就是簡單的用註解實現bean的裝配