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 2018-06-08 23:46  疯狂的妞妞  阅读(1368)  评论(0编辑  收藏  举报

导航