Java常见注解类
一、JDK自带注解
@Override
意思是:class子类implements
interface父类的方法
@Deprecated
意思是:方法过时了
@SuppressWarning("deprecation")
意思是:调用类里面的过时方法,会产生黄色波浪线警告,添加这个注解可以忽略这个警告
二、常见第三方注解
Spring
@Autowired
spring可以自动帮你把Bean里面引用的对象的setter/getter方法省略,它会自动帮你set/get。
@Autowired注释进行自动注入时,spring容器中匹配的候选Bean数目必须有且仅有一个。
当找不到一个匹配的Bean时,spring容器将抛出BeanCreationException异常,并指出必须至少拥有一个匹配的Bean。
如果spring容器中拥有多个候选Bean,spring容器在启动时也会抛出BeanCreationException
这个时候就可以借助@Qualifier注释指定注入Bean的名称,这样@Autowired就能解决多个候选Bean的问题
@Service
一个类带了@Service注解,将自动注册到Spring容器,不需要再在applicationContext.xml配置文件中定义bean了
@Repository
用在持久层的接口上,这个注解是将接口的一个实现类交给spring管理。
这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。 Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。1、@Service用于标注业务层组件
2、@Controller用于标注控制层组件(如struts中的action)
3、@Repository用于标注数据访问组件,即DAO组件.
4、@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
Mybatis
@InsertProvider
@UpdateProvider
@Options
注解的分类
从运行机制划分
1、源码注解
> 注解只在源码中存在,编译成.class文件就不存在了
2、编译时注解
> 注解在源码中和.class文件中都存在(JDK自带注解就属于这一类)
3、运行时注解
> 在运行阶段还起作用,甚至会影响运行逻辑的注解
从来源划分
1、来自JDK的注解
> 注解只在源码中存在,编译成.class文件就不存在了
2、来自第三方的注解
> 注解在源码中和.class文件中都存在(JDK自带注解就属于这一类)
3、我们自定义的注解
> 在运行阶段还起作用,甚至会影响运行逻辑的注解
特别划分:
元注解
是注解的注解
自定义注解
自定义注解的语法要求
public @interface Description{ ——————:使用@interface关键字定义注解
String desc(); ——————:成员以无参无异常方式声明
String author();
int age() default 18; ——————:可以用default 为成员指定一个默认值
}
1、成员类型是受限的,除了基本类型(像 int、float、double)以外,还包括String,Class,Annotation,Enumeration
2、如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)
3、注解类可以没有成员,没有成员的注解称为标识注解
注解的注解(元注解)
//元注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUMTIME)
@Inherited
@Documented
public @interface Description{
String desc();
String author();
int age() default 18;
}
@Target({ElementType.METHOD,ElementType.TYPE})
Target是注解的作用域: ↓↓
CONSTRUCTOR(构造方法声明) FIELD(字段声明) LOCAL_VARIABLE(局部变量声明)
METHOD(方法声明) PACKAGE(包声明) PARAMETER(参数声明) TYPE(类、接口)
@Retention(RetentionPolicy.RUMTIME)
Retention是注解的生命周期: ↓↓
SOURCE(只在源码显示,编译时会舍弃) CLASS(编译时会记录到class中,运行时忽略)
RUNTIME(运行时存在,可以通过反射读取)
@Inherited
Inherited是标识性注解:允许子类继承
@Documented
生成Javadoc时会包含注解(生成API文档)
工程右键Export————→选择Java文件夹下Javadoc————→选择路径新建文件夹Javadoc
点击Finish————→选择Yes to all————→然后打开Javadoc,打开index.html
使用自定义注解
使用注解的语法:@<注解名>(<成员名1>=<成员值1>,<成员名1>=<成员值1>,…)
@Description(desc="I am eyeColor",author="Mooc boy",age=18)
public String eyeColor(){
return "blue";
}
以上例子是:自定义注解Description在eyeColor()方法上使用
解析注解
概念:通过反射控制类、函数或成员上的运行时注射信息,从而实现动态控制程序运行的逻辑
一、自定义注解
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUMTIME)
@Inherited
@Documented
public @interface Description{
String value();
}
二、子类 dog.java,使用了自定义注解 Description()
三、在子类的类上注解为@Description("I am Superman");在子类的方法上注解为@Description("I am Jessica")
四、新建一个Parse类来进行————解析注解
public static void main(String[] args){
//1、使用类加载器加载类
try{
Class c= Class.forName("com.ann.test.dog");
//2、找到类上面的注解
boolean isExist=c.isAnnotationPresent(Description.class);
if(isExist){
//3、拿到注解实例
Description d=(Description)c.getAnnotation(Description.class);
System.out.println(d.value());//解析出来是dog上类的注解I am Superman
}
//4、找到方法上的注解
Method[] ms=c.getMethods();
for(Method m:ms){
boolean isMExist=m.isAnnotationPresent(Description.class);
if(isMExist){
Description d=(Description)m.getAnnotation(Description.class);
System.out.println(d.value());//解析出来是dog上方法的注解I am Jessica
}}
//另外一种解析方法
for(Method m:ms){
Annotation[] as=m.getAnnotations();
for(Annotation a:as){
if(a instanceof Description){
Description d=(Description)a;
System.out.println(d.value());//解析出来是dog上类的注解I am Jessica
}}}
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
自定义注解的Retention属性必须为RUMTIME,其他属性在测试解析注解输出为空
Inherited子类继承:
把接口父类改为class类并在类上和方法上添加自定义注解,
子类移除自定义注解,并由实现(implements)父类接口改为继承(extends)父类
运行Parse类,输出打印出父类的类上的注解
这意味着:子类继承父类的自定义注解,只能继承类上的自定义注解,方法上的自定义注解不能被继承