首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >一文带你看懂:不为人知的 package-info.java 文件

一文带你看懂:不为人知的 package-info.java 文件

作者头像
后台技术汇
发布于 2022-05-30 01:41:36
发布于 2022-05-30 01:41:36
2K00
代码可运行
举报
文章被收录于专栏:后台技术汇后台技术汇
运行总次数:0
代码可运行

许多同学日常开发时,都不太注意到,原来自己维护这么久的 web 工程中,居然还有 package-info.java 这么一个类。

但只要我们在 idea 中搜索一下,就能够发现很多依赖包,都用到了这个类的实现。

那么,下面我们一起研究下,到底什么是 package-info.java 类文件~~

【目录】

1)注解技术

2)package-info类拆解

3)动态ClassLoader原理 与 双亲委派机制

4)自定义ClassLoader

一、注解技术

注解(annotation)是 Java 5 引入的,用来为类、方法、字段、参数等 Java 结构提供额外信息的机制。我先举个例子,比如,Java 核心类库中的@Override注解是被用来声明某个实例方法重写了父类的同名同参数类型的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package java.lang;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

二、package-info类拆解

下面我们用一个简单的例子(分包逻辑开发),演示 package-info.java 的用法:

1)创建一个package:packageinfo

2)创建一个注解:PackageAnotation

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

/**
 * PackageAnotation.java 定义修饰包的注解
 * <b>package-info不是平常类,其作用有三个:</b><br>
 * 1、为标注在包上Annotation提供便利;<br>
 * 2、声明包的私有类和常量;<br>
 * 3、提供包的整体注释说明。<br>
 */
@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
@interface PackageAnotation {
  public String version() default "";
}

3)创建一个类,类名 = package-info.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制

/**
 * <b>package-info不是平常类,其作用有三个:</b><br>
 * 1、为标注在包上Annotation提供便利;<br>
 * 2、声明包的私有类和常量;<br>
 * 3、提供包的整体注释说明。<br>
 */
@PackageAnotation(version="1.0")
package packageinfo;

4)创建测试用例,类名 = TestPackageInfo.java

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package packageinfo;

/**
 * 测试package-info.java文件的作用
 * 1、为标注在包上Annotation提供便利;<br>
 * 2、声明包的私有类和常量;<br>
 * @author JoyoungZhang@gmail.com
 */
public class TestPackageInfo {
    public static void main(String[] args) {  
        //1 获取 Package 类
        Package p = Package.getPackage("packageinfo");
        //2 判断这个包对象,(是否在 package-info.java 中声明)且被某个注解(PackageAnotation)修饰
        if(p != null && p.isAnnotationPresent(PackageAnotation.class)) {
            //3 如果找到了注解,获取注解信息,实现业务逻辑(Servlet过滤、鉴权、分发请求等)
            PackageAnotation nav = p.getAnnotation(PackageAnotation.class);
            if (nav != null) {
                System.out.println("package version:" + nav.version());
            }
        }
    }
}

三、动态ClassLoader原理 与 双亲委派机制

3.1、动态ClassLoader原理

上面的测试用例,Package.getPackage("packageinfo"); 背后隐藏了一个原理 -- 类的动态加载。

写好一个Java程序,都是由若干个.class文件组织而成的一个完整的Java应用程序。当程序在运行时,即会调用该程序的一个入口函数,通过它来调用系统的相关功能;而这些功能都被封装在不同的class文件当中,所以经常要从这个class文件中要调用另外一个class文件中的方法。因此,如果另外一个文件不存在的,则会引发系统异常。而程序在启动的时候,并不会一次性加载程序所要用的所有class文件,而是按需通过Java的类加载机制(ClassLoader)来动态加载某个class文件到内存当中的,从而只有class文件被载入到了内存之后,才能被其它class所引用。

所以ClassLoader就是用来动态加载class文件到内存当中用的。

我们写好的应用类(业务代码),大部分都是通过这个类加载器 AppClassLoader 来加载到JVM里面。

3.2 JVM默认有3个默认类加载器

3.2.1 AppClassLoader

AppClassLoader 称为应用类加载器,又称为系统类加载器,负责在JVM启动时,加载来自在命令java中的classpath或者java.class.path系统属性或者CLASSPATH操作系统属性所指定的JAR包和类路径。

3.2.2 ExtClassLoader

ExtClassLoader 称为扩展类加载器,主要负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar包或者由java.ext.dirs系统属性指定的jar包.放入这个目录下的jar包对AppClassLoader加载器都是可见的(因为ExtClassLoader是AppClassLoader的父加载器,并且Java类加载器采用了委托机制)。

3.2.3 BootstrapClassLoader

BootstrapClassLoader 称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如:rt.jar、resources.jar、charsets.jar等,可通过如下程序获得该类加载器从哪些地方加载了相关的jar或class文件。

3.3 双亲委派机制

如果说,我们想引用一些外部依赖,那么就需要更高层的类加载器,让它们帮我们完成这个类装载的过程了,而这个过程也有个专有名词:双亲委派机制。

类加载分级:

-> 自定义ClassLoader

-> AppClassLoader

-> ExtClassLoader

-> BootstrapClassLoader

某个特定的类加载器在接到加载类的请求时,首先将加载任务委托交给父类加载器,父类加载器又将加载任务向上委托,直到最父类加载器,如果最父类加载器可以完成类加载任务,就成功返回,如果不行就向下传递委托任务,由其子类加载器进行加载。

总结

以上是关于package-info.java的相关知识介绍,还牵扯到了类加载器的回顾,希望对大家工作有所帮助。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后台技术汇 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
由浅入深谈 Java 的类加载机制
本文涉及知识点:双亲委托机制、BootstrapClassLoader、ExtClassLoader、AppClassLoader等。 什么是 Java 类加载机制? Java 虚拟机使用 Java
神秘的寇先森
2018/05/30
5840
阅读 Flink 源码前必知必会 - SPI 和 ClassLoader
Java 中的类加载器,是 Java 运行时环境的一部分,负责动态加载 Java 类到 Java 虚拟机的内存中。
kk大数据
2021/02/07
1.4K1
阅读 Flink 源码前必知必会 - SPI 和 ClassLoader
一文讲透 Tomcat 的类加载机制!揭秘类加载核心
你了解 Apache Tomcat 的类加载机制吗?本文将从底层原理切入,彻底揭秘 Tomcat 类加载所涉及的源码、机制和方案,助你深入掌握 Tomcat 类加载核心!
玄姐谈AGI
2021/01/11
2.3K0
一文讲透 Tomcat 的类加载机制!揭秘类加载核心
Java虚拟机 - 超级详细的类加载说明
java文件在编译时会被JVM编译成.class字节码文件,这篇主要讲解的是JVM如何将.class文件加载的加载过程。
虞大大
2020/08/26
4990
Java虚拟机 - 超级详细的类加载说明
【Tomcat源码篇】自定义类加载器那点儿事儿
  我们要分析清楚Tomcat中的类加载器相关的内容之前我们还是需要把JVM中的类加载器给大家理清楚。
用户4919348
2022/06/27
8790
【Tomcat源码篇】自定义类加载器那点儿事儿
Java学习记录--委派模型与类加载器
最近在读许令波的深入分析Java Web技术内幕一书,对于学习Java以来一直有的几个疑惑得到了解答,遂记录下来.
屈定
2018/09/27
6620
Java学习记录--委派模型与类加载器
《Java虚拟机原理图解》5. JVM类加载器机制与类加载过程
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.csdn.net/article/details/50529868
亦山
2019/05/25
1.3K0
类加载器详解
内容:转自 java知音 类加载器是负责将可能是网络上、也可能是磁盘上的class文件加载到内存中。并为其生成对应的java.lang.class对象。一旦一个类被载入JVM了,同一个类就不会被再次加载。 那么怎样才算是同一个类?在JAVA中一个类用其全限定类名(包名和类名)作为其唯一标识,但是在JVM中,一个类用其全限定类名和其类加载器作为其唯一标识。也就是说,在JAVA中的同一个类,如果用不同的类加载器加载,则生成的class对象认为是不同的。 当JVM启动时,会形成由三个类加载器组成的初始类加载器层
用户1257393
2018/01/30
7560
类加载器详解
JAVA ClassLoader双亲委派机制细节研究
我们都知道,Java类都是靠ClassLoader来加载的,而类加载器也是java类,因而java类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是java类,这个加载器正是BootstrapClassLoader。由于它不是Java类,因此它不需要被别人加载,而嵌套在Java虚拟机内核里面,也就是JVM启动的时候Bootstrap就已经启动,它是用C++写的二进制代码(不是字节码),它可以去加载别的类。
saintyyu
2021/11/22
4040
JAVA ClassLoader双亲委派机制细节研究
浅入Java ClassLoader
ClassLoader是用来加载Class 文件的。它负责将 Class 的字节码形式转换成内存形式的 Class 对象。字节码可以来自于磁盘文件 .class,也可以是 jar 包里的 .class,也可以来自远程服务器提供的字节流,字节码的本质就是一个字节数组 []byte,它有特定的复杂的内部格式。
日薪月亿
2019/05/14
3900
浅入Java ClassLoader
Java中常见的类加载器及双亲委派机制的原理
我们在代码里得到类的一个class对象,然后通过它的getClassLoader方法得到一个ClassLoader对象,那么运行一下看看这个ClassLoader对象的名字是什么
全栈程序员站长
2022/07/25
2530
Java中常见的类加载器及双亲委派机制的原理
JVM学习---类加载子系统
使用 BinaryViewer软件查看字节码文件,其开头均为 CAFE BABE ,如果出现不合法的字节码文件,那么将会验证不通过。
大忽悠爱学习
2021/11/15
2780
2.双亲委派机制详细解析及原理
研究类加载的过程就是要知道类加载的时候使用了双亲委派机制。但仅仅知道双亲委派机制不是目的,目的是要了解为什么要使用双亲委派机制,他的原理是什么?知道双亲委派机制的逻辑思想,然后这个思想是否可以被我们借鉴,为我所用。这才是学习知识的目的。
用户7798898
2021/10/09
7690
getClassLoader能否为null
我们Javaer都知道类想要被加载是需要一个个ClassLoader来执行的,并且类加载的方案叫双亲委派模式,说是双亲,其实就是单亲,可能我们最初的翻译人想让我们的加载器的家庭更完整吧,所以翻译成双亲。默认的类加载器包括BootstrapClassLoader、ExtClassLoader、AppClassLoader,他们都定义在在rt.jar中的sun.misc.Launcher类中,他们的”继承”关系是AppClassLoader—>ExtClassLoader—>BootstrapClassLoader,ExtClassLoader的parent获取不到BootstrapClassLoader,只能获取到一个null。
全栈程序员站长
2022/08/24
6820
getClassLoader能否为null
一文理解Java中的SPI机制
服务提供者接口(Service Provider Interface,简写为SPI)是JDK内置的一种服务提供发现机制。可以用来加载框架扩展和替换组件,主要是被框架的开发人员使用。在java.util.ServiceLoader的文档里有比较详细的介绍。
全菜工程师小辉
2021/06/25
1.8K0
一文理解Java中的SPI机制
聊聊类加载器与双亲委派模型
我们经常会在面试中遇到有关类加载器的问题,而作为一名Java开发人员应该了解类加载器如何工作?双亲委派模型是什么?如何打破双亲委派?为什么打破?等等。所以今天的主题就是聊一聊类加载器。
pjmike
2020/03/22
8790
相关推荐
由浅入深谈 Java 的类加载机制
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档