目录
1-3-2 在一个测试类 MyTestTest 上的添加几个方法
1-5-2 在jdbcutils工具类中提供一个getConnection,在方法上面添加一个注解 @JDBCInfo(...)
1-5-3 运行的时候可以通过getConnection获取一个连接
注解:了解注解,可以使用注解
servlet3.0:体验下注解,完成文件上传
类加载器(了解)
动态代理(★):加强方法
-
一、案例1-模拟junit测试
需求:
在一个类的方法中添加一个@MyTest,在另一个类的main方法中,就可以执行带有@MyTest的方法
技术分析:
注解
反射
-
1-1 注解
jdk5之后提供了一个特性,和类 接口同级
格式:
@interface 注解名{}
作用:
编译检查
替代配置文件
定义注解(元注解:注解上的注解)
分析代码(用到反射)
-
1-1 java中3个注解(理解)
- @Override:声明该方法是从父类上继承过来的,执行编译期的检查
- @SuppressWarnings:抑制警告 值有好多,只需要知道一个 all 抑制所有的警告
@SuppressWarnings("all")
- @Deprecated:声明 该方法不赞成使用(已过时,有bug)
-
1-2 自定义注解(理解)
-
1-2-1 注解属性
注解本质就是一个接口,接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
-
1-2-2 注解属性类型
- 基本类型
- String
- Class
- Annotation
- Enum:枚举(严格的类,不能new, 只能使用已经定义好的属性 private Color RED; )
Color RED();
- 以上类型对应的一维数组
public @interface MyAnnotation2 { //注解属性 int i(); String s(); //Date d(); String[] ss(); Class cl(); MyAnnotation1 m1(); Color RED(); }
注意:
一旦注解有属性了,使用注解的时候必须赋值,(除非这个注解属性有默认值)
-
1-2-3 赋值的格式
@注解名(属性名=属性值)
若注解类型为数组,且只有一个值的时候,可以有两种写法
方式1:
属性名 = { 值 } ss = {"qew", "123"}
方式2:
属性名=属性值 ss = "123"
若属性名为value的时候,且只需要为这个value属性赋值的时候,value可以省略//@MyAnnotaion3(i = 0) @MyAnnotaion3("") public class Demo3 { } public @interface MyAnnotaion3 { //int i(); //String s(); /** * int i(); String s(); String[] ss(); */ String value(); }
-
1-2-4 元注解:(理解)
定义在注解上的注解
@Retention 规定注解保留到什么阶段 值为RetentionPolicy的三个枚举值
SOURCE:只在代码中保留,在字节码文件中就删除了(默认)
CLASS:在代码和字节码文件中保留
RUNTIME:所有阶段都保留 (配置文件)
@Target 规定注解作用在什么上面 值为ElementType的枚举值
TYPE:作用在类 接口 等上面
METHOD:作用方法上面
FIELD:作用字段上面
-
1-3 步骤分析:(了解)
-
1-3-1 定义一个注解 @MyTest
//注解在运行时保留 @Retention(RetentionPolicy.RUNTIME) //注解只能作用在方法上 @Target(ElementType.METHOD) public @interface MyTest { }
-
1-3-2 在一个测试类 MyTestTest 上的添加几个方法
在方法上添加@MyTest
public class MyTestTest { @MyTest public void f1(){ System.out.println("f1方法执行了~~~~"); } public void f2(){ System.out.println("f2方法执行了~~~~"); } @MyTest public void f3(){ System.out.println("f3方法执行了~~~~"); } }
-
1-3-3 在另一个有主方法的类上添加main方法
运行main方法的时候,需要将带有 @MyTest注解的方法执行
//判断方法是否有指定的注解
boolean flag=m.isAnnotationPresent(MyTest.class);
package com.itheima.a_annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class MainTest { /*public static void main(String[] args) { //运行这个类的时候 需要将 测试类中带有@mytest所有方法执行 //获取字节码对象 Class clazz=MyTestTest.class; //获取所有的方法 Method[] arr = clazz.getMethods(); //让方法执行 for (Method m : arr) { //打印所有方法的名称 System.out.println(m.getName()); } }*/ public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { //运行这个类的时候 需要将 测试类中带有@mytest所有方法执行 //1 获取字节码对象 Class clazz=MyTestTest.class; //2 获取所有的方法 Method[] arr = clazz.getMethods(); //3 让带有注解的方法执行 for (Method m : arr) { //获取有注解的方法 //判断方法是否有指定的注解 boolean flag=m.isAnnotationPresent(MyTest.class); if(flag){ //System.out.println(m.getName()); m.invoke(clazz.newInstance()); } } } }
-
1-4 案例扩展- 通过注解获取连接的工具类
获取连接的工具类,通过注解,配置四个参数
-
1-5 步骤分析
-
1-5-1 自定义一个注解JDBCInfo
添加元注解:
在程序运行的时候使用 @Retention
只能作用在方法上 @Target
添加注解属性
String driverClass() default "com.mysql.jdbc.Driver"; //添加默认值
String url();
String username() default "root";
String password();@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface JdbcInfo { String driverClass() default "com.mysql.jdbc.Driver"; String url(); String user() default "root"; String password() default "root"; }
-
1-5-2 在jdbcutils工具类中提供一个getConnection,在方法上面添加一个注解 @JDBCInfo(...)
getConnection方法需要进行的操作:获取注解上的四个属性值
- 获取字节码文件
- 获取该方法上的注解