[email protected] 注解原理与使用

Java反射

java反射机制的定义:

在运行转态时(动态的)时。

对于任意一个类,都能够知道这个类的所有属性和方法

对于任意一个对象,都能够知道调用它的任意属性和方法

Class对象

java中用对象来对现实生活中的事物进行抽象,如人(现实生活)抽象到一个person类(java对象)。但有没有想过,java中的类(现实生活)其实也是一个Class对象(对象)。因此,这个Class类就包含了所有你定义的Class信息,包括所有的方法(私有,公有)、构造器、实现了那些方法、哪些注解信息、所有的属性等相关的信息,它还提供newInstance()方法来生成实例。

Class对象是一个相当特殊的对象,是一个超泛化的对象,是所有对象的对象。因此智能由JVM在创建其他对象的时候自动创建,因此Class对象又称包含了其他对象的字节码的信息的对象。

反射实现方法

 Class类是反射机制的起源,我们得到Class类对象有3种方法:

  第一种:通过类名获得

  Class<?> class = ClassName.class;

  第二种:通过类名全路径获得:

  Class<?> class = Class.forName("类名全路径");

  第三种:通过实例对象获得:

Class<?> class = object.getClass();

总结:第一种方法:类字面常量使得创建Class对象的引用时不会自动地初始化该对象,而是按照之前提到的加载,链接,初始化三个步骤,这三个步骤是个懒加载的过程,不使用的时候就不加载。

   第二种方法:Class类自带的方法。

   第三种方法:是所有的对象都能够使用的方法,因为getClass()方法是Object类的方法,所有的类都继承了Object,因此所有类的对象也都具有getClass()方法。

建议:使用类名.class,这样做即简单又安全,因为在编译时就会受到检查,因此不需要置于try语句块中,并且它根除了对forName()方法的调用,所以也更高效。

反射作用

看完反射的定义,我们就知道,反射机制就是增加了程序的灵活性,最重要的用途就是来开发通用型的框架,如Spring,将所有类的bean交给spring容器管理。无论是XML配置还是注解配置,当我们获取bean时,容器都会读取配置,这些配置就是类的信息,容器根据反射,生成实例返回。具体的作用还有动态代理、切面逻辑等等,其本质就是反射。

Java注解相关概念

什么是注解

注解(Annotation)就是Java提供了一种元程序中的元素关联任何信息或者任何元数据(metadata)的途径和方法,Annotation(注解)是一个接口,程序可以通过放射来获取指定的程序元素的Annotation对象,然后通过Annotation对象来获取注解里面的元数据。

Annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息。需要注意的是,这里存在着一个基本的规则:Annotation不能影响程序代码的执行,无论增加、删除Annotation,代码都始终如一的执行;另外,尽管一些annotation通过java的放射api方法在运行时被访问,而java语言解释器在工作时忽略了这些annotation。正是由于java虚拟机忽略了annotation,导致了annotation类型在代码中“不起作用”的;只有通过某种配套的工具才会对annotation类型中的信息进行访问和处理。

什么是metadata(元数据)

 元数据从metadata一词译来,就是“关于数据的数据”的意思。
  元数据的功能作用有很多,比如:你可能用过Javadoc的注释自动生成文档。这就是元数据功能的一种。总的来说,元数据可以用来创建文档,跟踪代码的依赖性,执行编译时格式检查,代替已有的配置文件。如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类: 
    1. 编写文档:通过代码里标识的元数据生成文档
    2. 代码分析:通过代码里标识的元数据对代码进行分析
    3. 编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查
  在Java中元数据以标签的形式存在于Java代码中,元数据标签的存在并不影响程序代码的编译和执行,它只是被用来生成其它的文件或针在运行时知道被运行代码的描述信息。
  综上所述:
    第一,元数据以标签的形式存在于Java代码中。
    第二,元数据描述的信息是类型安全的,即元数据内部的字段都是有明确类型的。
    第三,元数据需要编译器之外的工具额外的处理用来生成其它的程序部件。
    第四,元数据可以只存在于Java源代码级别,也可以存在于编译之后的Class文件内部。

Annotation和Annotation类型:

Annotation:

  Annotation使用了在java5.0所带来的新语法,它的行为十分类似public、final这样的修饰符。每个Annotation具有一个名字和成员个数>=0。每个Annotation的成员具有被称为name=value对的名字和值(就像javabean一样),name=value装载了Annotation的信息。

  Annotation类型:

  Annotation类型定义了Annotation的名字、类型、成员默认值。一个Annotation类型可以说是一个特殊的java接口,它的成员变量是受限制的,而声明Annotation类型时需要使用新语法。当我们通过java反射api访问Annotation时,返回值将是一个实现了该 annotation类型接口的对象,通过访问这个对象我们能方便的访问到其Annotation成员。

注解的分类:

  根据注解参数的个数,我们可以将注解分为三类:
    1.标记注解:一个没有成员定义的Annotation类型被称为标记注解。这种Annotation类型仅使用自身的存在与否来为我们提供信息。比如后面的系统注解@Override;
    2.单值注解
    3.完整注解  

根据注解使用方法和用途,我们可以将Annotation分为三类:
    1.JDK内置系统注解
    2.元注解
    3.自定义注解

系统内置标准注解:

注解的语法比较简单,除了@符号的使用外,他基本与Java固有的语法一致,JavaSE中内置三个标准注解,定义在java.lang中:
    @Override:用于修饰此方法覆盖了父类的方法;
    @Deprecated:用于修饰已经过时的方法;
    @SuppressWarnnings:用于通知java编译器禁止特定的编译警告。

元注解:

  元注解的作用就是负责注解其他注解。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解:
    [email protected],
    [email protected],
    [email protected],
    [email protected]

@Target

@Target说明了Annotation所修饰的对象范围。取值(ElementType)有

    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Retention

@Retention定义了该Annotation被保留的时间长短,如某些Annotation仅出现在源码中,而被编译器丢弃。取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留)
    2.CLASS:在class文件中有效(即class保留)
    3.RUNTIME:在运行时有效(即运行时保留)

属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理

@Documented

@Documented用于描述其他类型的annotation应该被作为被标注的程序成员公共的API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

@Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Column {

    public String name() default "fieldName";

    public String setFuncName() default "setField";

    public String getFuncName() default "getField";

    public boolean defaultDBValue() default false;

}

@Inherited

@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

自定义注解

package 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.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}

四、注解组合使用

Java spring开发时,经常在一个类上有多个注解,如SpringMVC注解

@RestController
@RequestMapping(‘/person’)

可以合并成一个

@PathRestController(‘/person’)

实现是

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;

import org.springframework.core.annotation.AliasFor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RestController
@RequestMapping
public @interface PathRestController {
    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};
}

原文地址:https://www.cnblogs.com/yanyouqiang/p/10955811.html

时间: 2024-08-08 01:04:29

[email protected] 注解原理与使用的相关文章

[email&#160;protected]注解与自动装配

1   配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss 拥有 Office 和 Car 类型的两个属性:       清单 3. Boss.java [java] view plaincopy package com.baobaotao; public class Boss { private Car car; private Office office

springboot情操陶冶[email&#160;protected]注解解析

承接前文springboot情操陶冶[email protected]注解解析,本文将在前文的基础上对@SpringBootApplication注解作下简单的分析 @SpringBootApplication 该注解是springboot最集中的一个注解,也是应用最广泛的注解.官方也多用此注解以启动spring服务,我们看下其中的源码 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inher

s[email&#160;protected]注解

自动将数据封装成json格式的数据返回回去 Maven <!-- Json Begin --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackso

springboot自动装配(1)[email&#160;protected]注解怎么自动装配各种组件

1.对于springboot个人认为它就是整合了各种组件,然后提供对应的自动装配和启动器(starter) [email protected]注解其实就是组合注解,通过它找到自动装配的注解@EnableAutoConfiguration,再由@EnableAutoConfiguration导入自动装配选择类AutoConfigurationImportSelector的selectImports方法去MATA-INF/spring.factories下面找到需要自动装配的组件的对应配置(各种Au

Spring高级话题[email&#160;protected]***注解的工作原理

出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy注解 激活Aspect自动代理 <aop:aspectj-autoproxy/> 开启对AspectJ自动代理的支持. 在用到AOP的自动代理的时候用,如果你理解了Java的动态代理,很容易的就会熟悉AOP的自动代理的. @EnableAsync @EnableAsync注解开启异步方法的支持. 这个相信大家都比较熟悉的.对于异步

[email&#160;protected]的原理解析

作为一个菜鸟,我有一颗好奇的心,每当vue init 的时候,看到那流畅的进度和神奇的结果,心里都充满一窥其本质的期望…… 以下就是我不断的console,大致理出来的一个流程心得,纪录在此,以作备忘. 1.which vue,定位vue命令的实际位置 2.去往命令vue的目录,查看代码 这里的commander包是用来创建命令行的工具,其npm官网粗略了解,了解到其中的init.list命令会在当前目录寻找执行vue-init.vue-list文件 The commander will try

Spring In [email&#160;protected]注解

//@Component注解会告诉Spring创建这个类的实例bean(注意,启动Component注解功能需要在xml里面配置,下面会将)@Component package com.zte.springinaction.soundsystem.imp; import org.springframework.stereotype.Component; import com.zte.springinaction.soundsystem.CompactDisc; //@Component注解会告诉

[email&#160;protected]注解

通过@ControllerAdvice.我们可以将对于控制器的全局配置放置在同一个位置,注解了@ControllerAdvice的类的方法可以使用@ExceptionHandler,@InitBinder,@ModelAttribute注解到方法上,这对所有注解了@RequestMapping的控制器内的方法有效. @ExceptionHandler:用于全局处理控制器里面的异常.@InitBinder:用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Mo

Hibernate一些_方法[email&#160;protected]注解_代码示例

操作数据库7步骤 :         1 创建一个SessionFactory对象        2 创建Session对象        3 开启事务Transaction : hibernate中,然后数据库操作,都必须是事务的,哪怕是查询        4 执行数据保存操作(必须提交,才会执行对应的操作方法)        5 提交事务        6 关闭Session                session.close();                getCurrentS