如何自定义注解

大家好,我是wave,这次来给大家讲一下自定义注解应该如何操作

基本概念

  • 注解是一个可以加强类的一个方式,我们可以通过注解的方式让一个类拥有更多的功能和含义。在Java中实现一个接口和继承一个类也可以改变一个类的功能,但注解这种方式相对来说会显得更加的简洁与方便。
  • 在Java中常见的注解有很多,比如@Override、@Deprecated、@FunctionalInterface。
  • @Override这个注解表示重写了父类的方法,其实这个注解仅仅是一个提示作用,并没有多少实际的作用。- @Deprecated这个注解表示这个方法已经过期,不建议开发者使用。
  • @FunctionalInterface这是Java1.8 新增的注解,用于约定函数式接口。
  • 目前注解开发已经是Java开发的一个趋势了,如果学习过框架的小伙伴都知道,框架里面的各种各样的注解实在是太方便了,可以极大的简化的开发的过程。
  • 但是我们需要思考,框架是别人造的轮子,我们不能只做一个只会用别人造的轮子的人,所以我们自己也需要学会造轮子,而造轮子的趋势就是使用注解,所以我们就得学习如何使用自定义注解。

基本操作

接下来的操作会实现一个名字为Wave的注解,然后模仿一下Mybatis里面的注解获取SQL语句。也就是把注解加在一个Mapper接口中的方法上,然后在一个类中去获取这个接口方法中的SQL语句。

首先定义一个注解

public @interface Wave {
  
}

这段代码就是定义了一个名为Wave的注解,注意是使用@interface。

元注解

  • @Target({METHOD,TYPE}) 表示这个注解可以用用在类/接口上,还可以用在方法上
  • @Retention(RetentionPolicy.RUNTIME) 表示这是一个运行时注解,即运行起来之后,才获取注解中的相关信息,而不像基本注解如@Override 那种不用运行,在编译时eclipse就可以进行相关工作的编译时注解。
  • @Inherited 表示这个注解可以被子类继承
  • @Documented 表示当执行javadoc的时候,本注解会生成相关文档

这几个元注解就是自定义注解开发的关键,根据上面的描述你会发现自己定义的注解上必须得有@Target与@Retention(RetentionPolicy.RUNTIME),因为注解肯定是要打在类、方法、属性等地方上的,并且得让它在程序运行时生效

修改自定义的注解

@Target({ElementType.METHOD,ElementType.TYPE})
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Wave {
    //这个表示注解可以有一个sql方法,并且返回一个String字符串
    String sql();
    //int port() default 3306;
}
  • 自定义注解里面的方法也可以有默认值,比如默认端口为3306则
  • int port() default 3306;

UserMapper接口

public interface UserMapper {
    @Wave(sql = "select * from xxx")
    public void query();
}

我们接下来就要在UserImpl中获取@wave里面的参数了

UserImpl

这段代码用到了一些反射的知识,如果不了解反射,请看Java反射基础篇

public class UserImpl  {

    public static void query() throws Exception{
        //使用反射获取UserMapper中的方法,再获取方法上的注解
        Wave config = UserMapper.class.getMethod("query").getAnnotation(Wave.class);
        //打印一下注解信息
        System.out.println(config);
        //获取注解的sql熟悉
        String sql = config.sql();
        System.out.println(sql);
    }

    @Test
    public void testAnnotation()throws Exception{
        query();
    }
}
如何自定义注解
运行结果

注解的基本使用就是这样的

演示JDBC使用注解

我们之前也讲过JDBC连接数据库的操作,我们本次使用注解再对DBUtil进行一个优化,如果对JDBC连接数据库操作不了解的请看JDBC连接数据库

JDBCConfig类

@Target({METHOD,TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface JDBCConfig {
    String ip();
    int port() default 3306;
    String database();
    String encoding();
    String loginName();
    String password();
}

优化DBUtil

//注解配置
@JDBCConfig(ip = "127.0.0.1", database = "test", encoding = "UTF-8", loginName = "root", password = "gt1010992686")
public class DBUtil {
    static {
        try {
            Class.forName("com.MySQL.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    //获取连接的静态方法
    public static Connection getConnection() throws SQLException, NoSuchMethodException, SecurityException {
        //解析注解内容
        JDBCConfig config = DBUtil.class.getAnnotation(JDBCConfig.class);
        
        //分别把每一个配置信息都取出来
        String ip = config.ip();
        int port = config.port();
        String database = config.database();
        String encoding = config.encoding();
        String loginName = config.loginName();
        String password = config.password();
        //拼接一下url
        String url = String.format("jdbc:mysql://%s:%d/%s?characterEncoding=%s", ip, port, database, encoding);
        //返回Connection
        return DriverManager.getConnection(url, loginName, password);
    }

    public static void main(String[] args) throws NoSuchMethodException, SecurityException, SQLException {
        Connection c = getConnection();
        System.out.println(c);//输出com.mysql.jdbc.JDBC4Connection@3f8f9dd6
    }
}

使用注解的这种方式配置会可能让配置看起来很简洁,这种配置也被应用在各种框架中

Ending

注解目前也是造轮子必备的一个技术,希望大家对这种开发模式有一定的了解与研究,而不是只会简单的使用注解

本次的分享到这里就结束了


往期推荐



扫描二维码

获取更多精彩

FingerDance



原文始发于微信公众号(FingerDance):如何自定义注解

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/26712.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!