天天看点

【framework】spring-注解(annotation)

近来发现把写博客当成任务了。呵呵,调整下了下心态:我在这里写,只是希望你看到,能有所帮助。

spring注解的发展史

然而我在一篇文章里,看到spring注解从1.2开始便有了,于是我不得不回头去查阅了下spring相关文档。得出如下结论:

1. spring1.0: 从1.0开始就在对元数据问题出谋划策,没有正式引入注解。但有了SOURCE级别的元数据支持

2. spring1.2: 在1.2的时候是java1.5的发布,并且面对要兼容1.3,1.4版本的问题,但已经有了基于java5.0的注解如: @ManagedResource,基本无关注。 aspectJ 在该版本中仍在建设过程中,还停留在aspect。

3. spring2.0 :有了比较多的注解,包括AspectJ已经采用了注解方法,并且支持xml配置

4. spring2.5: 引入了用于配置的完整的Annotation集合: @Autowired,以及对JSR-250注解@Resource, @PostConstruct and @PreDestroy的支持

5. spring3.0: 注解已经非常的丰富,spring的 JavaConfig项目已经加入到spring框架中,这意味着将直接支持如@Configuration,@Bean,@Value等标签

6. spring3.1: 对@Configuration有所增强,充实。 

认识注解:

我相信大家接触注解(annotation),最早应该是@Override,@Deprecated,@Suppress Warnings,就算接触不多,也没关系,我这里尽量系统的说一遍。

1. 注解:也被叫做 元数据(其实我觉得更是元数据的一种表现形式),为代码添加信息提供了一种形式化的方法,在稍后的某个时候用到这些数据

2. 元数据: 用于描述数据的数据(MetaDate),翻译成信息的信息会跟更好理解,举例来说:我这边文章就是一些数据,或者信息,而对这个文章的标题,时间,关键字,都可以称为元数据

3. 注解是元数据与源代码结合在一起,但不保存在外部文档(如xml)的趋势下催生的

阴暗的说,其实你知道上面这些也没大用,反正能写能用就成,下面介绍注解的格式 

注解的格式

注意: 注解本身不做任何事

注解可以与其他任何修饰符共同作用于方法,例如public,static或者void。从语法角度看,注解的使用方式与修饰符使用几乎一模一样。

为何说几乎,举例:

有方法:

  public void create(int i){}

和 注解

  @Test, @Test1

可以如下写法:

1.

@Test  

public void create(int i){} 

2.

public @Test void create(int i){}  

@Test public void create(int i){}   

//注意不能放在void的后面 

3.

public void create(@Test int i){}  

4.

@Test@Test1  

public void create(int i){}  

//注解以@分隔,与空白符包括行(row) 无关 

 java中自定义一个注解和应用:

只举一个简单例子,算是入门。但对你理解spring注解将会是个不错的过渡,至少你能感觉到,注解原来这么简单。

例子:

import java.lang.annotation.*;   

@Target(ElementType.METHOD)//注解只能用于方法   

@Retention(RetentionPolicy.RUNTIME)//注解在运行期也保留,可以通过反射读取注解信息   

public @interface Scholar {   

    public int id();   

    public String descrition() default "no description";   

}  

建立一个类TestScholar 来应用@Scholar

代码:

public class TestScholar {   

    @Scholar(id=1)   

    public void test() {};   

  效果图:

<a href="http://yjplxq.blog.51cto.com/attachment/201208/29/4081353_1346230162jr70.png"></a>

通过上面的例子,对注解算是有些认识。注意:

1. @Target如果你是第一次接触,不要急,下面有讲解

2. 你需要注意 注解的方式很像接口,字段定义需要加小括号

3. 注解可以有缺省,如果缺省(default),则可以不赋值

元注解

记得元数据的解释吗?是的,元注解专职负责注解其他注解 

参数

说明

@Target

表示注解可用于什么地方

CONSTRUCTOR

构造器的声明

FIELD

域声明(包括enum实例)

LOCAL_VARIABLE

局部变量声明

METHOD

方法声明

PACKAGE

包声明

PARAMETER

参数声明

TYPE

类,接口(包括注解)或者enum声明

@Retention

表示需要什么级别保存该注解信息

SOURCE

注解将被编译器丢弃

CLASS

注解在class文件中可用,会被VM丢弃

RUNTIME

VM在运行期被保留,可以通过反射机制读取注解

@Documented

将此注解包含在Javadoc中

@Inherited

允许子类集成父类中的注解

 注解类型

所有基本类型(int,float,boolean等)

String

Class

enum

Annotation

以上类型的数组

读取注解的内容:

通过反射机制,都会有getAnnotation()方法

如方法(Method)的: 

for(Method m : of.getDeclaredMethods())  

Scholar scholar = m.getAnnotation(Scholar.class)  

如果是初学,可能要去专门学习下,呵呵,这里只是为了给spring做个入门。

spring2.5 注解

spring2.5算是一个里程碑的版本,而注解2个比较大的改革便是:

1. Annotation驱动的bean配置

2. 对Spring MVC的支持

分别讲解一下:

1.Annotation驱动的bean配置

1.1 基于注解(Annotation-based)的配置

要使注解可用,您必须使用 Java 5 (Tiger)或更新的版本,以使得可以访问源代码层次的注解。这些注解可以被注册为独立 bean 的定义,但它们也可以被隐式地注册,通过基于 XML 的配置方式,如下例(请注意包含 'context' 命名空间):

&lt;?xml version="1.0" encoding="UTF-8"?&gt; 

&lt;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"&gt; 

&lt;context:annotation-config/&gt;     

  &lt;!--注意:xmlns:context="http://www.springframework.org/schema/context" --&gt;        

  &lt;!--(隐式注册 post-processors 包括了

&lt;/beans&gt; 

1.2 @Autowired

引用些官方例子:

1)@Autowired 注解可以用于“传统的”setter 方法,如下例:

public class SimpleMovieLister {  

    private MovieFinder movieFinder;  

    @Autowired  

    public void setMovieFinder(MovieFinder movieFinder) {  

        this.movieFinder = movieFinder;  

    }  

    // ...  

2)这个注解也可以用于以属性为参数/多个参数的方法

public class MovieRecommender {  

    private MovieCatalog movieCatalog;  

    private CustomerPreferenceDao customerPreferenceDao;  

    public void prepare(MovieCatalog movieCatalog,  

            CustomerPreferenceDao customerPreferenceDao) {  

        this.movieCatalog = movieCatalog;  

        this.customerPreferenceDao = customerPreferenceDao;  

    } 

// ...  

3)@Autowired注解甚至可以用于构造器与字段:

    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {  

4)也可以一种提供来自ApplicationContext的特殊类型的所有 beans,注解字段或者方法,例如:

    private MovieCatalog[] movieCatalogs;   

5)这同样适用于集合类型:

    private Set&lt;MovieCatalog&gt; movieCatalogs;  

    public void setMovieCatalogs(Set&lt;MovieCatalog&gt; movieCatalogs) {  

        this.movieCatalogs = movieCatalogs;  

    }   

注意:在缺省情况下,当出现0个候选的 beans时自动连接将失败;缺省行为把连接方法,构造器,字段假设为 required 的依赖。这样的行为如下所示:

    @Autowired(required = false)  

1.3 基于注解的微调

1)有多个实例,需要筛选出一个,可以通过Qualifier注解

    @Qualifier("mainCatalog")  

    private MovieCatalog movieCatalog;   

2)@Qualifier注解也能够被指定为构造器的参数或者方法的参数:

    public void prepare(@Qualifier("mainCatalog") MovieCatalog movieCatalog,  

2.对Spring MVC的支持

Spring 2.5 为MVC 控制器引入了一种基于Annotation(注解)的编程模型, 使用@RequestMapping, @RequestParam, @ModelAttribute等等注解。 

1.要实现控制器@Controller自动探测

加入配置

&lt;!--package是要扫描的包--&gt;

&lt;context:component-scan base-package="org.springframework.samples.petclinic.web"/&gt; 

2.一个实例

@Controller  

@RequestMapping("/editPet.do")  

@SessionAttributes("pet")  

public class EditPetForm {  

    private final Clinic clinic;  

    public EditPetForm(Clinic clinic) {  

        this.clinic = clinic;  

    @ModelAttribute("types")  

    public Collection&lt;PetType&gt; populatePetTypes() {  

        return this.clinic.getPetTypes();  

    @RequestMapping(method = RequestMethod.GET)  

    public String setupForm(@RequestParam("petId") int petId, ModelMap model) {  

        Pet pet = this.clinic.loadPet(petId);  

        model.addAttribute("pet", pet);  

        return "petForm";  

    @RequestMapping(method = RequestMethod.POST)  

    public String processSubmit(@ModelAttribute("pet") Pet pet,  

            BindingResult result, SessionStatus status) {  

        new PetValidator().validate(pet, result);  

        if (result.hasErrors()) {  

            return "petForm";  

        } else {  

            this.clinic.storePet(pet);  

            status.setComplete();  

            return "redirect:owner.do?ownerId=" + pet.getOwner().getId();  

        }  

spring2.5 对注解的2个主要关注点已经阐述,但是随着注解的大量应用,spring可能融入一些其他的框架,如AspectJ ,都会有自己的注解,需要大家了解并且注意,但是他并不是与spring-framework实际相关。

收尾

我想这些东西,很多人都应该写过,这里就不反复阐述。我写文章的目的,是为spring3新特征和加强(包括注解)做铺垫,有时间就写写。

本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/yjplxq/976539,如需转载请自行联系原作者