java扫描包

在 Java 中,经常会有扫描某个包,然后找出全部的 Class 的需求。

spring 工具

想使用 spring 的扫描功能,前提是对象要注册到容器。

AbstractApplicationContext (上下文)、ConfigurableListableBeanFactory(BeanFactory)等对象均可使用。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Controller;

class BeanFactoryPostProcessorExample implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        //获取带有 Controller 注解的 Bean
        String[] names= beanFactory.getBeanNamesForAnnotation(Controller.class);
    }
}

Controller 是 spring 自带的注解,所以能被 spring 扫描到,如果想自己设计一个类似的注解:

在你设计的注解上,加一个 @Component 即可。

import org.springframework.stereotype.Component;

/**
 * 自定义的注解上,加一个 @Component 注解
 */
@Component
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface QuartzScheduled {
}

/**
 * 添加 @QuartzScheduled 注解之后,LogDeleteJob 就能被 spring 扫描到了
 */
@QuartzScheduled
public class LogDeleteJob extends BaseJob {

    @Override
    public void handler(ScheduleJob job, ScheduleLog scheduleLog) {
        SpringContext.getBean(AccessLogService.class).deletePreMonthData();
    }
}

Reflections

Reflections 这个工具包也很不错,Maven 的依赖如下:

<dependencys>
    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>22.0</version>
    </dependency>
    <dependency>
      <groupId>org.reflections</groupId>
      <artifactId>reflections</artifactId>
      <version>0.9.10</version>
    </dependency>
    <dependency>
      <groupId>org.javassist</groupId>
      <artifactId>javassist</artifactId>
      <version>3.15.0-GA</version>
    </dependency>
</dependencys>

样例:

class Test{
    public static void main(String[] args) {
        Reflections reflections = new Reflections("com.sea.server.hessian");
        Set<Class<?>> hessianImpls = reflections.getTypesAnnotatedWith(Controller.class);
    }
}

编码实现

实战过程中,一般选用前面两个方案,你可能想展示一下自身的硬实力,自己编码实现:

代码编译之后,“.class 文件目录” 与 “代码目录” 是完全一致的,可以通过遍历文件的方式,完成对代码的扫描。

比如:下面的 Symbol 文件,位于 cn/seaboot/commons/bean 文件夹下,所以它的全类名是 cn.seaboot.commons.bean.Symbol。

如果你的代码已经打成 jar 包了,就需要遍历 jar 包内部文件,代码与读取 zip 类似,可以专门学习一下。

(没什么应用场景,代码基本废弃,这里只能提供理论支持了)

posted on   疯狂的妞妞  阅读(1383)  评论(0编辑  收藏  举报

(评论功能已被禁用)
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示