gpt4 book ai didi

JavaWeb Spring注解Annotation深入学习

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 28 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章JavaWeb Spring注解Annotation深入学习由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

1、注解 。

注解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 。

最后此篇关于JavaWeb Spring注解Annotation深入学习的文章就讲到这里了,如果你想了解更多关于JavaWeb Spring注解Annotation深入学习的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com