基本结构:
public @interface 注解名称{
}
属性声明:
public @interface 注解名称{
//声明注解的属性
public 属性类型 属性名() default 默认值;
}
//属性类型:基本数据类型、String、Class、注解、枚举Enum;以上类型一维数组
//属性名:自定义
//默认值:与类型匹配即可
实例
package com.czxy.d6_annotation;
import java.util.Date;
/** 注解定义
*/
public @interface MyAnno {
public String username() default ""; //字符串
public int age() default 0; //基本数据类型
public double salary() default 0;
public Class clazz() default String.class; //字节码对象
public MySonAnno msa() default @MySonAnno; //其他注解
public MyGender mg() default MyGender.FEMALE; //枚举
public String[] hobbies() default {}; //一维数组
}
元注解:用于修饰自定义注解
的官方注解
。
官方注解(元注解)
自定义注解
使用位置(类、字段、构造、方法等)
自定义注解
生命周期,保留的时间。
package com.czxy.d7_annotation2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*/
@Target({ElementType.TYPE , ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface MyAnno2 {
public String value() default "";
public String[] hobbies() default {};
}
基本使用:
@注解名
属性使用
@注解名(属性名=值, 属性名2=值2, ...);
//如果是一位数组,需要使用{}填写多个值
实例:
package com.czxy.d6_annotation;
/** 注解使用
*/
@MyAnno(username="jack",age=18,salary=10.0,clazz=String.class,msa=@MySonAnno, mg=MyGender.FEMALE, hobbies={"抽烟","喝酒","烫头"} )
public class TestAnno {
@MyAnno
public String username = "jack";
@MyAnno
public TestAnno() {
}
@MyAnno
public void info() {
}
}
package com.czxy.d7_annotation2;
/**
*/
public @interface MyAnno2 {
public String value() default "";
public String[] hobbies() default {};
}
属性类型为数组,值如果只有一个,{}可以省略。
//@MyAnno2(hobbies = {"a","b"}) //标准写法
//@MyAnno2(hobbies = "a") //{}省略
如果只有一对属性,且属性名为value,value可以省略
//@MyAnno2(value = "") //标准写法
//@MyAnno2("") //只有一对,value省略
@MyAnno2(value="", hobbies = {}) //value不能省略
综合:
package com.czxy.d7_annotation2;
/**
*/
public @interface MyAnno3 {
public String[] value();
}
//@MyAnno3(value={"a"}) //标准写法
//@MyAnno3(value="a") //{}省略
@MyAnno3("a") //value省略
允许解析
解析注解API
测试注解
package com.czxy.d8_annotation;
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)
public @interface MyAnno4 {
public String username();
public String password();
}
测试代码
package com.czxy.d8_annotation;
import java.lang.reflect.Method;
/**
*/
public class TestAnno4 {
@MyAnno4(username = "jack",password = "6666")
public void info() {
}
public static void main(String[] args) throws Exception {
//1 获得方法Method
// 1.1 获得Class
Class clazz = Class.forName("com.czxy.d8_annotation.TestAnno4");
// 1.2 获得Method
Method infoMethod = clazz.getMethod("info");
//2 判断Method上是否有MyAnno4注解
boolean r = infoMethod.isAnnotationPresent(MyAnno4.class);
//3 获得注解
if(r) {
//有
MyAnno4 anno4 = infoMethod.getAnnotation(MyAnno4.class);
String username = anno4.username();
String password = anno4.password();
System.out.println(username);
System.out.println(password);
} else {
System.out.println("没有");
}
}
}
注解
package com.czxy.d9_annotaion4_demo;
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)
public @interface MyTest {
}
测试类
package com.czxy.d9_annotaion4_demo;
import java.lang.reflect.Method;
/**
*/
public class Main {
@MyTest
public void info() {
System.out.println("----------------info");
}
// @MyTest
public void show() {
System.out.println("-------------show");
}
public static void main(String[] args) throws Exception {
//需求:执行当前类的被@MyTest修饰的方法,有几个执行几个!
//info执行
//1 获得class
Class clazz = Class.forName("com.czxy.d9_annotaion4_demo.Main");
//2 创建实例
Object obj = clazz.newInstance();
//3 获得所有的方法
Method[] allMethod = clazz.getMethods();
//4 遍历所有方法
for(Method method: allMethod) {
//5 判断当前方法是否有@MyTest
boolean r = method.isAnnotationPresent(MyTest.class);
if(r) {
//6 如果有,执行方法
method.invoke(obj);
} else {
//7 如果没有,提示
// System.out.println(method.getName() + ",没有注解");
}
}
}
}
代理:代理的作用,就是对目标进行增强的。
动态代理:程序在运行时,动态创建代理类,对目标类进行代理(增强)。
package com.czxy.d10_proxy;
public interface UserService {
public void add();
public String update();
public String delete();
}
package com.czxy.d10_proxy;
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("目标类UserServiceImpl.add");
}
@Override
public String update() {
System.out.println("目标类UserServiceImpl.update");
return "update";
}
@Override
public String delete() {
System.out.println("目标类UserServiceImpl.delete");
return "delete";
}
}
package com.czxy.d10_proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestProxy {
public static void main(String[] args) {
//正常使用,目标类
UserService userService = new UserServiceImpl();
userService.add();
//动态代理
//1 类加载器:每一个类都需要一个类加载器将其加载到内存中,(固定代理)
ClassLoader classLoader = TestProxy.class.getClassLoader();
//2 代理需要实现的所有接口
Class[] interfaces = {UserService.class};
//3 代理类处理类
InvocationHandler invocationHandler = new InvocationHandler(){
/*
参数1:proxy,代理类
参数2:method,代理类当前执行的方法
参数3:args,方法的实际参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//方法名
String methodName = method.getName();
//增强
if("delete".equals(methodName)) {
System.out.println("对delete进行增强");
return null;
}
//代理类中,调用目标类对应的方法
Object result = method.invoke(userService, args);
return result;
}
};
//4 使用工具生成代理类
UserService proxyUserService = (UserService)Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);
proxyUserService.add();
String u = proxyUserService.update();
System.out.println("代理类:" + u);
String d = proxyUserService.delete();
System.out.println("代理类:" +d);
}
}