Day54 元注解补充、综合案例、request/response

1.思维导图

2.代码部分

元注解

  • @Target

  定义

@Target(value = {
        ElementType.TYPE ,
        ElementType.FIELD ,
        ElementType.METHOD ,
        ElementType.PARAMETER ,
        ElementType.LOCAL_VARIABLE }
        )
public @interface MyAnnotation01 {

    String value() default "hello annotation";

}

  使用

@MyAnnotation01
public class Demo01 {

    @MyAnnotation01
    private int num = 1;

    @MyAnnotation01
    public static void main(@MyAnnotation01 String[] args) {

        @MyAnnotation01
        int num = 1;
    }
}
  • @Retention

  定义

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation01 {

    String value() default "hello annotation";

}

自定义注解@MyTest

  • @MyTest注解
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
    String value() default "";
}
  • Test01测试类
 1 public class Test01 {
 2 
 3     @Test
 4     public void test01(){
 5         System.out.println("test01");
 6     }
 7 
 8     @MyTest
 9     public void test02(){
10         System.out.println("test02");
11     }
12 
13     @MyTest
14     public void test03(){
15         System.out.println("test03");
16     }
17 
18     public void test04(){
19         System.out.println("test04");
20     }
21 
22 }
  •  demo类
 1 public class Demo02 {
 2 
 3     public static void main(String[] args) {
 4         //使用反射,扫描Test01类里面有哪些方法有@MyTest注解
 5         //如果有@MyTest注解,就将其执行
 6         //如果没有@MyTest注解,不做任何处理
 7 
 8         //1,获取Test01类对应的Class对象
 9         Class<Test01> clazz = Test01.class;
10         //2,获取Test01类下所有的方法对象
11         Method[] methods = clazz.getMethods();
12         //stream流 lambda表达式
13         Arrays.stream(methods).forEach(method -> {
14             //method就是单个方法对象
15             //3,判断方法上是否有@MyTest注解
16             boolean present = method.isAnnotationPresent(MyTest.class);
17             if (present) {
18                 //方法上有@MyTest注解,执行方法
19                 try {
20                     method.invoke(clazz.newInstance());
21                 } catch (Exception e) {
22                     e.printStackTrace();
23                 }
24             } else {
25                 //方法上没有@MyTest注解
26             }
27         });
28     }
29 }

自定义注解@JDBCInfo

 1 @Target(ElementType.TYPE)
 2 @Retention(RetentionPolicy.RUNTIME)
 3 public @interface JDBCInfo {
 4 
 5     String driverClass() default "com.mysql.jdbc.Driver";
 6     String jdbcUrl() default "jdbc:mysql://localhost:3306/day53";
 7     String user() default "root";
 8     String password() default "root123";
 9 
10 } 

 

在JDBCUtils工具类上使用@JDBCInfo

  • 反射读取注解@JDBCInfo中的内容

 1 @JDBCInfo(password="1234")
 2 public static Connection getConnection() throws Exception{
 3    /**
 4    * 获得当前类上的getConnection方法.
 5      * 获得该方法上的@JDBCInfo这个注解.
 6      * 获得这个注解中的属性的值.
 7      * 使用这些值为下面参数设置值.
 8      */
 9   // 获得JDBCUtils的类的Class对象.
10   Class clazz = JDBCUtils.class;
11   // 获得getConnection方法:
12   Method method = clazz.getMethod("getConnection", null);
13   // 获得方法上的注解:
14   JDBCInfo jdbcInfo = method.getAnnotation(JDBCInfo.class);
15   // 获得注解中的属性的值:
16   String driverClass = jdbcInfo.driverClass();
17   String url = jdbcInfo.url();
18   String username = jdbcInfo.username();
19   String password = jdbcInfo.password();
20   // 加载驱动:
21   Class.forName(driverClass);
22   // 获得连接:
23   Connection conn = DriverManager.getConnection(url, username, password);
24   return conn;
25 }

反射、注解、设计模式初级版

  • 自定义注解@SystemLog
1 @Retention(RetentionPolicy.RUNTIME)
2 public @interface SystemLog {
3 
4     String className();//记录类名
5     String methodName();//记录方法名
6 
7 }

 

  •  设置@SystemLog中className属性、methodName属性
 1 public interface UserDao {
 2 
 3     @SystemLog(className = "com.qfedu.dao.UserDao" , methodName = "addUser")
 4     void addUser() throws Exception;
 5 
 6     void deleteUser() throws Exception;
 7 
 8     @SystemLog(className = "com.qfedu.dao.UserDao" , methodName = "updateUser")
 9     void updateUser() throws Exception;
10 
11 }

 

  •  编写装饰者设计模式
 1 public class UserDaoWrapper implements UserDao{
 2 
 3     private UserDao userDao;
 4 
 5     public UserDaoWrapper(UserDao userDao) {
 6         this.userDao = userDao;
 7     }
 8 
 9     @Override
10     public void addUser() throws Exception {
11         userDao.addUser();
12         printLog("addUser");
13     }
14 
15     @Override
16     public void deleteUser() throws Exception {
17         userDao.deleteUser();
18         printLog("deleteUser");
19     }
20 
21     @Override
22     public void updateUser() throws Exception {
23         userDao.updateUser();
24         printLog("updateUser");
25     }
26 
27     /**
28      * 日志记录
29      * @param runMethodName
30      */
31     private void printLog(String runMethodName) throws Exception {
32         //判断接口上对应的方法中是否有@SystemLog注解
33         //获取UserDao接口实现子类的Class对象
34         Class<? extends UserDao> sonClazz = userDao.getClass();
35         //获取UserDao接口的Class对象
36         Class<?>[] interfaces = sonClazz.getInterfaces();
37         Class<?> fatherClazz = interfaces[0];
38         //获取接口中对应的方法对象(addUser方法)
39         Method method = fatherClazz.getMethod(runMethodName);
40         if (null !=  method) {
41             //判断方法上是否有@SystemLog注解
42             boolean present = method.isAnnotationPresent(SystemLog.class);
43             if (present) {
44                 //方法有@SystemLog注解,打印日志
45                 SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
46                 Date currentDate = new Date();
47                 String currentTimeStr = format.format(currentDate);
48                 SystemLog systemLog = method.getAnnotation(SystemLog.class);
49                 String className = systemLog.className();
50                 String methodName = systemLog.methodName();
51                 System.out.println(currentTimeStr + " --- " + className + "类中 ---" + methodName + "()方法 --- 运行了");
52             }
53         }
54 
55     }
56 }

反射、注解、设计模式优化版

  • 自定义注解@SystemLog
1 @Retention(RetentionPolicy.RUNTIME)
2 public @interface SystemLog {
3 
4     String className();//记录类名
5     String methodName();//记录方法名
6 
7 }

 

  •  设置@SystemLog中className属性、methodName属性
 1 public interface UserDao {
 2 
 3     @SystemLog(className = "com.qfedu.dao.UserDao" , methodName = "addUser")
 4     void addUser() throws Exception;
 5 
 6     void deleteUser() throws Exception;
 7 
 8     @SystemLog(className = "com.qfedu.dao.UserDao" , methodName = "updateUser")
 9     void updateUser() throws Exception;
10 
11 }

 

  •  动态代理
 1         UserDao userDao = new UserDaoImpl();
 2         UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(
 3                 userDao.getClass().getClassLoader(),
 4                 userDao.getClass().getInterfaces(),
 5                 new InvocationHandler() {
 6                     @Override
 7                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 8                         //获取到接口中方法对象 , 比如 : UserDao接口中addUser方法
 9                         //之前
10                         //先获取实现子类的Class对象
11                         //再获取到接口的Class对象
12                         //再获取到接口中的方法对象
13                         //现在
14                         //再获取到接口的Class对象  -- userDao.getClass().getInterfaces(),
15                         //再获取到接口中的方法对象  --  Method method
16                         //method : 就是接口中的方法对象
17                         Object returnValue = null;
18                         if (null != method) {
19                             boolean present = method.isAnnotationPresent(SystemLog.class);
20                             if (present) {
21                                 //如果有@SystemLog注解 , 执行原有功能 ,  打印日志
22                                 returnValue = method.invoke(userDao, args);
23                                 String currentTimeStr = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss")
24                                         .format(new Date());
25                                 SystemLog systemLog = method.getAnnotation(SystemLog.class);
26                                 String className = systemLog.className();
27                                 String methodName = systemLog.methodName();
28                                 System.out.println(currentTimeStr + " --- " + className + "类中 ---" + methodName + "()方法 --- 运行了");
29                             } else {
30                                 //如果没有@SystemLog注解, 执行原有功能, 不打印日志
31                                 returnValue = method.invoke(userDao, args);
32                             }
33                         }
34 
35                         return returnValue;
36                     }
37                 });
38 
39         userDaoProxy.addUser();

 

posted @ 2020-04-16 20:33  Her4c  阅读(141)  评论(0编辑  收藏  举报