一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - JavaWeb Spring注解Annotation深入學習

JavaWeb Spring注解Annotation深入學習

2020-06-14 11:09i10630226 JAVA教程

這篇文章主要為大家詳細介紹了JavaWeb Spring注解Annotation,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、注解

注解Annotation,是一種類似注釋的機制,在代碼中添加注解可以在之后某時間使用這些信息。跟注釋不同的是,注釋是給我們看的,java虛擬機不會編譯,注解也是不編譯的,但是我們可以通過反射機制去讀取注解中的信息。注解使用關鍵字@interface,繼承java.lang.annotition.Annotition

1、javaSE中的注解

先舉個例子來回顧一下在javaSE中注解是什么東東,關鍵是兩點,注解的定義與如何通過反射得到注解上面的信息。

1.先定義兩個注解一個是在類上有注解ClassInfo,一個是在方法上有注解為MethodInfo.

ClassInfo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.itheima10.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.TYPE) //該注解可以用于類上
@Retention(RetentionPolicy.RUNTIME) //在java,class文件以及運行時注解都起作用
@Documented //能生成在幫助文檔中
public @interface ClassInfo {
 /**
  * 該注解有兩個String類型的屬性
  * @return
  */
 String name() default "";
 String value() default "";
}

MethodInfo

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.itheima10.annotation;
 
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.METHOD) //該注解可以用于方法上
@Retention(RetentionPolicy.RUNTIME) //在java,class文件以及運行時注解都起作用
@Documented //能生成在幫助文檔中
public @interface MethodInfo {
 /**
  * 該注解有兩個String類型的屬性
  */
 String name() default "";
 String value() default "";
}

2.寫一個類AnnotationUse來使用上面定義的注解

?
1
2
3
4
5
6
7
8
9
package com.itheima10.annotation;
 
@ClassInfo(name="小平果118",value="牛")
public class AnnotationUse {
 @MethodInfo(name="java",value="spring框架很重要")
 public void java(){
 
 }
}

3.編寫測試類AnnotationTest,解析上述兩個注解上面的屬性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.itheima10.annotation;
 
import java.lang.reflect.Method;
 
import org.junit.Test;
 
public class AnnotationTest {
 public static void test(){
  /**
   * 如果解析類的注解,先得到Class
   * 如果解析方法的注解,先得到method
   */
  Class class1 = Itheima10.class;
  //判斷類上面是否有ClassInfo注解
  if(class1.isAnnotationPresent(ClassInfo.class)){
   //得到類上面的注解
   ClassInfo classInfo = (ClassInfo)class1.getAnnotation(ClassInfo.class);
   System.out.println(classInfo.value());
   System.out.println(classInfo.name());
  }
 
  Method[] methods = class1.getMethods();
  for (Method method : methods) {
   //正在遍歷的方法上面是否存在MethodInfo注解
   if(method.isAnnotationPresent(MethodInfo.class)){
    MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);
    System.out.println(methodInfo.name());
    System.out.println(methodInfo.value());
   }
  }
 }
 
 @Test
 public void test(){
  AnnotationTest.test();
 }
}

2、spring中的注解

spring框架為我們提供了注解功能。

使用注解編程,主要是為了替代xml文件,使開發更加快速。但是,xml文件的使用就是解決修改程序修改源代碼,現在又不去使用xml文件,那么不就違背了開閉原則了么,得確是。不過么,注解也有注解的好,使用注解就不用配置那么多的xml文件啦,最重要的是開發效率高。。

在沒有使用注解時,spring框架的配置文件applicationContext.xml文件中需要配置很多的<bean>標簽,用來聲明類對象。使用注解,則不必在配置文件中添加標簽拉,對應的是在對應類的“注釋”位置添加說明。具體介紹如下:
 •1.@Resource 對象間關系的組合,默認采用的是按名稱方式進行裝配,如果根據名稱查找不到關聯的對象,那么會再采用按類型繼續查找。如果沒有指定name屬性,

• 當注解標注在字段上,即默認取字段的名稱作為bean名稱尋找依賴對象
• 當注解標注在屬性的setter方法上,即默認取屬性名作為bean名稱尋找依賴對象。

JavaWeb Spring注解Annotation深入學習

• 注意:如果沒有指定name屬性,并且按照默認的名稱找不到依賴對象時, @Resource注解會回退到按類型裝配。但一旦指定了name屬性,就只能按名稱裝配了。

 •2. @Autowired
@Autowired 默認按類型裝配,@Resource默認按名稱裝配,當找不到與名稱匹配的bean才會按類型裝配。 解是按類型裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它required屬性為false。

 •3、 @Qualifier
如果我們想使用按名稱裝配,可以結合@Qualifier注解一起使用。 

1、使用注解,需要在配置文件中增加命名空間和約束文件步驟:

引入context命名空間

<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"
           ...
                     
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

2、 在配置文件中加入context:annotation-config標簽

<context:annotation-config></context:annotation-config>

實例演示:

編寫一個Person類,其中有一個student屬性,以及一個say()方法,代碼如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.itheima10.spring.di.annotation;
 
import javax.annotation.Resource;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
 
/**
 * @Autowired//按照類型進行匹配
 *
 * @Autowired//按照類型進行匹配
 @Qualifier("student")
 *
 */
public class Person {
 @Resource(name="student")
 private Student student;
 
 public void say(){
  this.student.say();
 }
}

Student類代碼如下

?
1
2
3
4
5
6
7
package com.itheima10.spring.di.annotation;
 
public class Student {
 public void say(){
  System.out.println("student");
 }
}

配置applicationContext.xml文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  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-2.5.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 <!--
  把person和student放入到spring容器中
  -->
 <bean id="person" class="com.itheima10.spring.di.annotation.Person"></bean>
 <bean id="student" class="com.itheima10.spring.di.annotation.Student"></bean>
 <!--
  引入context命名空間
   xmlns:context="http://www.springframework.org/schema/context"
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-2.5.xsd"
  -->
  <!--
  啟動了以來注入的注解解析器
  -->
  <context:annotation-config></context:annotation-config>
</beans>

編寫測試類AnnotationTest

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package com.itheima10.spring.di.annotation;
 
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
 * 原理:
 * 1、啟動spring容器
 * 2、把person和student兩個bean實例化
 * 3、當spring容器解析到
 *   <context:annotation-config></context:annotation-config>
 *  就會啟動依賴注入的注解解析器
 * 4、spring容器會在納入spring管理的bean的范圍內查找,看這些類的哪些屬性上加有@Resource注解
 * 5、如果某一個屬性上加有@Resource注解
 *   會查看該注解的name屬性的值是否為""
 *    如果為"",則會把該注解所在的屬性的名稱和spring容器中的id的值作匹配,如果匹配成功,則賦值
 *     如果匹配不成功,則按照類型進行匹配,匹配成功則賦值
 *       如果再匹配不成功,則報錯
 *    如果不為"",則把該注解的name屬性的值和spring容器中id的值作匹配,如果匹配成功,則賦值
 *     如果匹配不成功,則直接報錯
 *          
  說明:
   注解只能作用于引用類型
   xml與注解的對比
    xml的效率比較高,書寫比較麻煩
     注解的書寫比較簡單,效率比較低
 *
 */
public class AnnotationTest {
 @Test
 public void testAnnotation(){
  ApplicationContext context =
     new ClassPathXmlApplicationContext("applicationContext.xml");
  Person person = (Person)context.getBean("person");
  person.say();
 }
}

如果使用注解,就不需要在配置文件中裝載person和student了,這樣就可以簡化配置文件的編寫。

3、 掃描

前面的例子我們都是使用XML的bean定義來配置組件。在一個稍大的項目中,通常會有上百個組件,如果這些組件采用xml的bean定義來配置,顯然會增加配置文件的體積,查找及維護起來也不太方便。spring2.5為我們引入了組件自動掃描機制,它可以在類路徑底下尋找標注了@Component、@Service、@Controller、@Repository注解的類,并把這些類納入進spring容器中管理。它的作用和在xml文件中使用bean節點配置組件是一樣的。要使用自動掃描機制,我們需要打開以下配置信息:

1、引入context命名空間

在xml配置文件中添加context:component-scan標簽

其中base-package為需要掃描的包(含子包)。

實例:
將上述實例用掃描的方式書寫如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component
public class Person {
 @Resource(name="student")
 private Student student;
 
 public void say(){
  this.student.say();
 }
}
 
@Component
public class Student {
 public void say(){
  System.out.println("student");
 }
}

applicationContext.xml只需配置一句話

?
1
2
3
4
5
6
<!--
 component 組件
  把一個類放入到spring容器中,該類就稱為組件
  在base-package指定的包及子包下掃描
 -->
 <context:component-scan base-package="com.itheima10.spring.scan"></context:component-scan>

編寫測試類AnnotationTest

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
 * 原理
 * 1、啟動spring容器
 * 2、spring容器解析
 *  <context:component-scan base-package="com.itheima10.spring.scan">
   </context:component-scan>
  3、在base-package指定的包及子包中掃描,看哪些類上面是否含有@Component注解
  4、如果有該注解
  @Component
  public class Person {
  }
  ==等價于
  <bean id="person" class="..Person">
  @Component("aa")
  public class Person {
  }
  ==等價于
  <bean id="aa" class="..Person">
  5、按照@Resource的解析步驟執行
 說明:
   整個過程掃描兩次,效率越來越低,書寫越來越簡單
 *
 *
 */
public class AnnotationTest {
 @Test
 public void testAnnotation(){
  ApplicationContext context =
     new ClassPathXmlApplicationContext("applicationContext.xml");
  Person person = (Person)context.getBean("person");
  person.say();
 }
}

實例再現

我們將Item51中最后的文檔管理系統用注解的方式改一下,Document接口不變,有read和write方法,實現類分別如下ExcelDocument ,PDFDocument ,WordDocument 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Component("excelDocument")
public class ExcelDocument implements Document{
 
 public void read() {
  System.out.println("excel read");
 }
 public void write() {
  System.out.println("excel write");
 }
 
}
 
@Component("pdfDocument")
public class PDFDocument implements Document{
 
 public void read() {
  System.out.println("pdf read");
 }
 public void write() {
  System.out.println("pdf write");
 }
 
}
 
@Component("wordDocument")
public class WordDocument implements Document{
 
 public void read() {
  System.out.println("word read");
 }
 public void write() {
  System.out.println("word write");
 }
 
}

DocumentManager

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@Component("documentManager")
public class DocumentManager {
 @Resource(name="excelDocument")
 private Document document;
 
 public void read(){
  this.document.read();
 }
 
 public void write(){
  this.document.write();
 }
}

配置文件

    <context:component-scan base-package="com.itheima10.spring.iocdi.document">
    </context:component-scan>

編寫測試類DocumentTest

?
1
2
3
4
5
6
7
8
9
public class DocumentTest {
 @Test
 public void testDocument(){
  ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  DocumentManager documentManager = (DocumentManager)context.getBean("documentManager");
  documentManager.read();
  documentManager.write();
 }
}

2、其他注解功能介紹
@Service用于標注業務層組件、服務層注解
@Controller用于標注控制層組件(如struts中的action)、控制層注解
@Repository用于標注數據訪問組件,即DAO組件。持久層注解

而@Component泛指組件,當組件不好歸類的時候,我們可以使用這個注解進行標注。

實例重現–MVC案例

我們再次回顧Item51中的MVC案例,分別將PersonDaoImpl ,PersonAction ,PersonServiceImpl 的Dao,Service,Action層加上注解有

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Repository("personDao")
public class PersonDaoImpl implements PersonDao {
 @Override
 public void savePerson() {
  System.out.println(" save person");
 }
}
 
@Service("personService")
public class PersonServiceImpl implements PersonService{
 @Resource(name="personDao")
 private PersonDao personDao;
 
 public void setPersonDao(PersonDao personDao) {
  this.personDao = personDao;
 }
 @Override
 public void savePerson() {
  this.personDao.savePerson();
 
 }
 
}
 
@Controller("personAction")
public class PersonAction {
 @Resource(name="personService")
 private PersonService personService;
 
 public void setPersonService(PersonService personService) {
  this.personService = personService;
 }
 
 public void savePerson(){
  this.personService.savePerson();
 }
}

編寫測試MVCTest

?
1
2
3
4
5
6
7
8
9
public class MVCTest {
 @Test
 public void testMVC(){
  ApplicationContext context =
     new ClassPathXmlApplicationContext("applicationContext.xml");
  PersonAction personAction = (PersonAction)context.getBean("personAction");
  personAction.savePerson();
 }
}

4. spring中的繼承

Spring支持繼承,可以分為類繼承和屬性繼承

1. 類繼承

Spring屬性:
(1)abstract: 如果設置為true,表示定義的bean是抽象的,告訴spring不要實例化這個bean;
問題:必須是抽象類么?可以不是抽象類么?
(2)parent: 指明bean的id,對bean的作用,相當于extends對于java類的作用;

場景:有三個Bean:

?
1
2
3
4
5
6
7
8
9
<bean id = "bean1" class = "……TestBean">
 <property name="sex" value="male"/>
</bean>
<bean id = "bean2" class = "……TestBean">
 <property name="sex" value="male"/>
</bean>
<bean id = "bean3" class = "……TestBean">
 <property name="sex" value="female"/>
</bean>

修改:定義spring 父bean

?
1
2
3
<bean id ="BaseBean" class ="……TestBean">
 <property name="sex" value="male"/>
</bean>

定義子Bean

?
1
2
3
4
5
<bean id ="bean1" parent = "BaseBean"/>  繼承父Bean的屬性
<bean id ="bean2" parent = "BaseBean"/>  
<bean id ="bean3" parent = "BaseBean">  覆蓋父Bean的屬性
 <property name="sex" value="female"/>
</bean>

子bean可以繼承父Bean的屬性,也可以覆蓋父Bean的屬性

2. 屬性繼承

幾個不同Bean之間存在相同的屬性,可以抽離出來
場景:

?
1
2
3
4
5
6
7
<bean id = "bean1" class = "……ATestBean">
 <property name="sex" value="male"/>
 <property name="task" ref="task"/>
</bean>
<bean id = "bean2" class = "……BTestBean">
 <property name="sex" value="male"/>
</bean>

修改:(1) 抽取公共屬性

?
1
2
3
<bean id = "baseSex" abstract="true">
 <property name="sex" value="male"/>
</bean>

(2)bean修改

?
1
2
3
4
<bean id = "bean1" class = "……ATestBean" parent="baseSex">
 <property name="task" ref="task"/>
</bean>
<bean id = "bean2" class = "……BTestBean" parent="baseSex"/>

這里bean同時有parent和class屬性,其中parent指向的baseSex,就是為了讓不同Bean之間共享相同的屬性值;在TransactionProxyFactoryBean聲明業務時,Bean屬性繼承能夠明顯的減少冗余的xml配置。

基于注解的繼承無需要parent屬性。

最后上一張小小的總結圖吧

JavaWeb Spring注解Annotation深入學習

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/i10630226/article/details/50518369

延伸 · 閱讀

精彩推薦
  • JAVA教程java多線程抓取鈴聲多多官網的鈴聲數據

    java多線程抓取鈴聲多多官網的鈴聲數據

    很容易就能發現通過改變 listId和page就能從服務器獲取鈴聲的json數據, 通過解析json數據, 可以看到都帶有{"hasmore":1,"curpage":1}這樣子的指示,通過判斷ha...

    bobo_ll1412020-04-21
  • JAVA教程老生常談 java匿名內部類

    老生常談 java匿名內部類

    下面小編就為大家帶來一篇老生常談java匿名內部類。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧 ...

    jingxian3352020-05-29
  • JAVA教程java基于Socket做一個簡單下載器

    java基于Socket做一個簡單下載器

    這篇文章主要為大家詳細介紹了java如何基于Socket制作一個簡單下載器,感興趣的小伙伴們可以參考一下 ...

    yesz123583102020-06-07
  • JAVA教程Java網絡編程基礎教程之Socket入門實例

    Java網絡編程基礎教程之Socket入門實例

    這篇文章主要介紹了Java網絡編程基礎教程之Socket入門實例,本文講解了創建Socket、Socket發送數據、Socket讀取數據、關閉Socket等內容,都是最基礎的知識點,需要...

    junjie4442019-11-28
  • JAVA教程深入剖析java中String、StringBuffer、StringBuilder的區別

    深入剖析java中String、StringBuffer、StringBuilder的區別

    下面小編就為大家帶來一篇深入剖析java中String、StringBuffer、StringBuilder的區別。小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過...

    jingxian3702020-04-29
  • JAVA教程java的五種數據類型解析

    java的五種數據類型解析

    下面小編就為大家帶來一篇java的五種數據類型解析。小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧 ...

    jingxian1552020-04-28
  • JAVA教程Java中二叉樹數據結構的實現示例

    Java中二叉樹數據結構的實現示例

    這篇文章主要介紹了Java中二叉樹數據結構的實現示例,包括前中后序遍歷和求二叉樹深度的方法,需要的朋友可以參考下 ...

    zinss269142042020-01-02
  • JAVA教程Java基礎知識之Java語言概述

    Java基礎知識之Java語言概述

    這篇文章主要介紹了Java基礎知識之Java語言概述,本文介紹了Java語言相關的基礎知識、歷史介紹、主要應用方向等內容,需要的朋友可以參考下 ...

    Java教程網3952019-12-10
主站蜘蛛池模板: 国产网站免费观看 | 爱欲荡漾在线观看 | 美国一级大黄大色毛片 | 天堂69亚洲精品中文字幕 | 草留色区 | 日韩美毛片 | 91短视频版高清在线观看免费 | 亚洲成色www久久网站 | 粗了大了 整进去好爽视频 刺激一区仑乱 | 天天做天天爱天天爽综合区 | 2022国产麻豆剧传媒剧情 | 亚洲欧美日韩精品 | 欧美第一视频 | yy6080欧美三级理论 | 国产成人欧美 | 亚洲日韩欧美一区二区在线 | 青青青手机在线视频 | 欧美性高清另类videosex死尸 | 日韩一级精品视频在线观看 | 免费一级片在线观看 | 精品亚洲欧美中文字幕在线看 | 无限在线观看视频大全免费高清 | 亚洲视频在线一区二区三区 | 亚洲国产精品综合福利专区 | 德国高清freexxxx性 | 52zfl宅福利yxpjw | 青草国产福利视频免费观看 | 特黄特黄一级高清免费大片 | 色v在线 | 国产精品1区2区 | 男同gay玩奴男同玩奴 | 女子监狱第二季未删减在线看 | 秘书喂奶好爽一边 | 国产精品免费网站 | 26uuu久久 | 国内精品久久久久久久久久久久 | 日韩手机在线观看 | 色综合久久夜色精品国产 | 厨房play黄瓜进入 | 三级伦理影院 | 国产精品一区牛牛影视 |