注解:
一、什么是注解:是元数据,即一种描述数据的数据。
语法格式:@注解类型名
注解可以出现在类上、属性上、方法(包括构造方法)上、参数上等。
注解可以出现在注解类型上。
注解的作用:主要功能就是起到一个标识作用。比如:Spring框架如果是基于注解开发,IOC主要负责解耦,核心容器只要存放实体Bean,但是这时spring框架不知道究竟要管理哪些实体Bean,然后就可以通过spring提供的注解来进行标识,spring会启动扫描器扫描当前工程所有的类,如果发现被扫描的类有spring提供的注解,然后该类就会装载进spring容器。
二、元注解:用来修饰注解的注解。
在定义注解时需要通过元注解指定被修饰注解的使用场合、是否生成文档、是否可以继承、注解保持的策略。
注解可以定义属性:包括所有基本数据类型,String,枚举
如果一个注解指定了属性,在使用此注解时,要给属性赋值!(除非已经赋予了默认值)。
如果属性有且仅有value,赋值时可以省略属性名。
public @interface MyAnnotation {//在注解中定义属性 注意:不是方法String value();int age();double num();enum s{};}
import com.jy.annotation.MyAnnotation;@MyAnnotation(value = "key",age=12,num=3.14)public class Demo01 {public static void main(String[] args) {}}
default :注解中给属性赋予默认值的关键字。
public @interface MyAnnotation {//在注解中定义属性 注意:不是方法String value() default "key";int age() default 12;double num()default 3.14;enum s{};}
@MyAnnotation()public class Demo01 {public static void main(String[] args) {}}
三、案例:
需求:工程中如果实体Bean上有IdAnnotation注解修饰的话,在实体类中就必须含有私有的id属性,否则程序抛出异常
class.properties
classes = com.jy.pojo.Person;com.jy.pojo.User;
User类
package com.jy.pojo;import com.jy.annotation.IdAnnotation;@IdAnnotationpublic class User {private String name;public User(String name) {this.name = name;}public User() {}public String getName() {int i;return name;}public void setName(String name) {this.name = name;}}
Person类
package com.jy.pojo;import com.jy.annotation.IdAnnotation;@IdAnnotationpublic class Person {private int id;}
Demo
package com.jy.demo;import com.jy.annotation.IdAnnotation;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.IOException;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.lang.reflect.Modifier;import java.util.Properties;public class Demo01 {public static void main(String[] args) {try {FileReader fileReader = new FileReader("class");Properties properties = new Properties();properties.load(fileReader);//获取所有实体bean的全类名String classes = properties.getProperty("classes");//将字符串通过分号切割String[] split = classes.split(";");for (String s : split) {//获取字节码对象Class aClass = Class.forName(s);//获取注解,判断实体bean中是否有@IdAnnotation注解修饰Annotation annotation = aClass.getAnnotation(IdAnnotation.class);if(annotation !=null ){//根据字节码获取属性Field[] declaredFields = aClass.getDeclaredFields();for (Field declaredField : declaredFields) {if(declaredField.getName().equals("id") && Modifier.toString(declaredField.getModifiers()).contains("private")){System.out.println("该实体bean符合要求"+aClass);}else {throw new BeanIdNotFoundException("该类没有私有的id属性:"+aClass);}}}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}}}
自定义异常:BeanIdNotFoundException
package com.jy.demo;public class BeanIdNotFoundException extends RuntimeException{public BeanIdNotFoundException(String message) {super(message);}}
四、通过反射获取注解
Demo02
package com.jy.demo;import com.jy.annotation.Filed;import com.jy.annotation.IdAnnotation;import com.jy.pojo.Person;import java.lang.reflect.Field;/*** 通过反射获取注解(很重要,spring的IOC涉及这个操作)*/public class Demo02 {public static void main(String[] args) throws Exception{//获取字节码对象Class<Person> personClass = Person.class;//获取类上的注解IdAnnotation annotation = personClass.getAnnotation(IdAnnotation.class);//注解进行强转IdAnnotation idAnnotation = (IdAnnotation)annotation;//通过注解获取属性String name = idAnnotation.name();Field[] declaredFields = personClass.getDeclaredFields();for (Field declaredField : declaredFields) {Filed annotation1 = declaredField.getAnnotation(Filed.class);System.out.println(annotation1);}}}
Filed:
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Filed {}
Person类
@IdAnnotationpublic class Person {@Filedprivate int id;@Filedprivate int age;@Filedprivate String name;}
