Spring入門-基本注解的使用


前面創建和管理對象使用xml配置文件來完成,但是隨着對象的增多,xml配置文件也越來越大,為了防止這種現象的發生,注解的使用就應運而生。注解是在類或方法前面添加特定以"@+注解名"開頭的標識,實現xml配置文件的功能,如前面學習的創建對象、配置作用域、配置延遲加載等功能等。

組件掃描

容器會掃描指定的包及子包下面所有的類,如果該類前面有特定的注解,比如@Component,則容器會將其納入管理,不需要在xml中配置bean,其作用相當在配置文件中配置一個bean元素,bean的id是帶注解@Component的類的第一個字母小寫后的名稱

組件掃描的使用方法:

step1 在類面前添加特定的注解,比如@Component默認的id是類首字母小寫后的名

step2 在我們的配置文件當中,配置組件掃描

1 <context:component-scan base-package="package_name"/> <!--其中package_name代表我們要掃描的包-->

只有在組件類定義前面有如下注解標記時,才會掃描到Spring容器來管理,為后續使用其他注解提供必要條件。

@Component 通用注釋,spring框架的,Rod Johnson大神寫的

@Named 通用注釋,SUN公司的,模仿Spring的注釋,現在很少用,需要導額外的包

@Repository 持久化層組件注解,一般用於訪問數據庫

@Service 業務層組件注解,用於業務邏輯處理  

@Controller 控制層組件注解

基本注解使用

后期做項目時,如果是控制層的類需加注解@Controller,如果是業務層的類需加@Service,如果是持久層的類需加@Repository,其他類使用@Component來添加。這里測試都是使用@Component來完成。

前期准備工作,是配置組件掃描,掃描我的測試包com.boe。

1         <!-- 配置組件掃描 -->    
2         <context:component-scan base-package="com.boe"></context:component-scan>

(1)創建對象、作用域、延遲加載、生命周期使用注解

創建一個People類來使用注解。

 1 package com.boe;
 2 
 3 import javax.annotation.PostConstruct;
 4 import javax.annotation.PreDestroy;
 5 
 6 import org.springframework.context.annotation.Lazy;
 7 import org.springframework.context.annotation.Scope;
 8 import org.springframework.stereotype.Component;
 9 
10 @Component("p")
11 @Scope("singleton")
12 @Lazy(false) 
13 public class People {
14     //默認構造方法
15     public People() {
16         System.out.println("創建一個人");
17     }
18     
19     //初始化方法和銷毀方法的注解,需導入tomcat
20     @PostConstruct 
21     public void init() {
22         System.out.println("初始化了");
23     }
24     @PreDestroy
25     public void destroy() {
26         System.out.println("銷毀了");
27     }    
28 }
View Code

junit測試

1     //測試@Component、作用域、延遲加載和生命周期
2     @Test
3     public void test1() {
4         String path="myIOC.xml";
5         AbstractApplicationContext ac=new ClassPathXmlApplicationContext(path);
6         People people=ac.getBean("p",People.class);
7         System.out.println(people);
8         ac.close();
9     }
View Code

測試結果

可以看出通過注解就可以創建對象,如圖是在作用域為singleton,延遲加載為false的情況下結果,其跟前面使用xml配置文件的效果是一樣的。需要注意的是配置銷毀方法只對singleton有效。

(2)使用@Autowired和@Qualifier依賴注入

這種方法適用於set方法和構造器方法注入,注解的位置可以寫在屬性前面,也可以寫在set或構造器方法前面,區別就是前者只能注入,后者是可以在set或構造器方法里添加其他的邏輯。默認情況下是byType類型注入,如果要指定名字需要配合@Qualifier("name")來使用。

案例通過將people注入到國家類和省類對象中來完成。

case1 set方法注入,將people注入到country

Country類

 1 package com.boe;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Qualifier;
 5 import org.springframework.stereotype.Component;
 6 
 7 @Component
 8 public class Country {
 9     //屬性
10     private People people;
11     //get set方法
12     public People getPeople() {
13         return people;
14     }
15     @Autowired
16     public void setPeople(@Qualifier("p")People people) {
17         this.people = people;
18     }
19     //構造方法
20     public Country() {
21         System.out.println("創建一個新的國家");
22     }
23     //重寫toString方法
24     @Override
25     public String toString() {
26         return "Country [people=" + people + "]";
27     }
28 }
View Code

junit測試

1     //測試使用@Autowired和@Qualifier注解-set方法注入
2     @Test
3     public void test2() {
4         String path="myIOC.xml";
5         ApplicationContext ac=new ClassPathXmlApplicationContext(path);
6         Country c=ac.getBean("country",Country.class);
7         System.out.println(c);
8     }
View Code

測試結果

case2 構造器注入,將people注入到province

Province類

 1 package com.boe;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Qualifier;
 5 import org.springframework.stereotype.Component;
 6 
 7 @Component
 8 public class Province {
 9     //屬性
10     private People people;
11     //帶參數構造方法
12     @Autowired
13     public Province(@Qualifier("p")People people) {
14         System.out.println("新建一個省,有人民");
15         this.people = people;
16     }
17     //默認構造方法
18     public Province() {
19         System.out.println("新建一個省,沒有人民");
20     }
21     //重寫toString
22     @Override
23     public String toString() {
24         return "Province [people=" + people + "]";
25     }    
26 }
View Code

junit測試

1     //測試使用@Autowired和@Qualifier注解-構造方法注入
2     @Test
3     public void test3() {
4         String path="myIOC.xml";
5         ApplicationContext ac=new ClassPathXmlApplicationContext(path);
6         Province province=ac.getBean("province",Province.class);
7         System.out.println(province);
8     }
View Code

測試結果

(3)使用@Resource依賴注入 

這種注解只適合set方法注入,並且默認情況下是byName類型,如果@Resource(name="")里沒有添加名字或name找不到,則按照byType方式。

案例通過將people注入到縣類對象中來完成。

Village類

 1 package com.boe;
 2 
 3 import javax.annotation.Resource;
 4 
 5 import org.springframework.stereotype.Component;
 6 
 7 @Component
 8 public class Village {
 9     //屬性
10     private People people;
11     //set方法
12     @Resource(name="p")
13     public void setPeople(People people) {
14         this.people = people;
15     }
16     //構造方法
17     public Village() {
18         System.out.println("新建了一個村");
19     }
20     //重寫
21     @Override
22     public String toString() {
23         return "Village [people=" + people + "]";
24     }    
25 }
View Code

junit測試

1     //測試使用@Resource-set方法注入
2     @Test
3     public void test4() {
4         String path="myIOC.xml";
5         ApplicationContext ac=new ClassPathXmlApplicationContext(path);
6         Village v=ac.getBean("village",Village.class);
7         System.out.println(v);
8     }
View Code

測試結果

(3)使用@Value注入值

使用@Value注解,配合spring表達式的使用,可以將值注入到對象。

UserBean類

 1 package com.boe;
 2 
 3 import org.springframework.beans.factory.annotation.Value;
 4 import org.springframework.stereotype.Component;
 5 
 6 @Component("user")
 7 public class UserBean {
 8     @Value("clyang") //name賦值為clyang
 9     //@Value("")也可以用在set方法前,區別就是屬性前使用只能賦值,如果set方法前寫除了賦值外還可以寫其他的功能
10     private String name;
11     //讀取properties屬性文件
12     @Value("#{config.pageSize}") //使用spring表達式
13     private String pageSize;
14     
15     public String getName() {
16         return name;
17     }
18     public void setName(String name) {
19         this.name = name;
20     }
21     public String getPageSize() {
22         return pageSize;
23     }
24     public void setPageSize(String pageSize) {
25         this.pageSize = pageSize;
26     }
27     @Override
28     public String toString() {
29         return "UserBean [name=" + name + ", pageSize=" + pageSize + "]";
30     }
31 }
View Code

xml配置文件中添加對properties文件的讀取

<!-- 讀取properties屬性文件 -->
<util:properties id="config" location="classpath:config.properties"></util:properties>

junit測試

 1     //測試用@Value注解,注入值(基本數據類型或者集合)
 2     @Test
 3     public void test5() {
 4         //路徑配置文件
 5         String path="myIOC.xml";
 6         //啟動spring容器,使用AbstractApplicationContext子接口
 7         ApplicationContext ac=new ClassPathXmlApplicationContext(path);
 8         //得到userBean
 9         UserBean ub=ac.getBean("user", UserBean.class);
10         System.out.println(ub);        
11     }
View Code

測試結果

 

結論

(1)使用注解可以減少xml配置文件中的內容,並且可以實現跟xml一樣的功能,原則是能使用注解的盡量使用注解,不能使用的就使用配置文件完成。

(2)@Resource默認采用byName類型注入,@Autowired默認采用byType,如果要改byName需配合@Qualifier一起使用

(3)@Resource來自JaveEE,需要有包annotation,@Autowired和@Qualifier來自Spring,參考下圖

 

參考博文

(1)https://www.cnblogs.com/youngchaolin/p/11332783.html

(2)https://www.cnblogs.com/Jason-Xiang/p/5345342.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM