一、项目

二、自定义注解

package org.rockcode.annotations;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableFruit {
  String name() default "EnableFruit";
}

三、services 目录

package org.rockcode.services;
public interface Fruit {
public String getName();
}
package org.rockcode.services;
import org.rockcode.annotations.EnableFruit;
@EnableFruit
public class Apple implements Fruit{
@Override public String getName() {
return "Apple";
}
}

三、扫描services目录下面@EnableFruit的类

public class ClassPathEnableEnumScanner {

//解析路径下的 class
private static final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
//转换成 MetaData 读取类
private static final SimpleMetadataReaderFactory register = new SimpleMetadataReaderFactory(); public static void getClazzFromAnnotation(String pkgPath, Class<? extends Annotation> annotationClass) { //获取spring的包路径
String pathPackage = "classpath*:org/rockcode/services/**/*.class"; // 返回的是 FileSystemResource 数组
// file [E:\idea\SpringIOC\target\classes\org\rockcode\services\Apple.class]
// file [E:\idea\SpringIOC\target\classes\org\rockcode\services\Banana.class]
// file [E:\idea\SpringIOC\target\classes\org\rockcode\services\Fruit.class]
// file [E:\idea\SpringIOC\target\classes\org\rockcode\services\Orange.class]
Resource[] resources = new Resource[0];
try {
//加载路径下的资源
resources = resolver.getResources(pathPackage);
} catch (IOException e) { }
for (int i = 0; i < resources.length; i++) {
Resource resource = resources[i]; MetadataReader metadataReader = null;
try {
//读取资源
// 返回 classMetadata annotationMetadata
metadataReader = register.getMetadataReader(resource);
} catch (IOException e) {
continue;
} //读取资源的注解配置
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata(); //判断是否包含注解,如果有则继续,没有就重新遍历
if (!annotationMetadata.hasAnnotation(annotationClass.getName())) continue; //类信息
ClassMetadata classMetadata = metadataReader.getClassMetadata(); //类全名
String className = classMetadata.getClassName();
try {
//加载类
Class<?> clazz = Class.forName(className);
// 这里的逻辑是注册到 beanDefinitionMap,实现方式很多,通过 clazz 实例化对象,调用相关方法,等等
// todo } catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
getClazzFromAnnotation("org.rockcode.services", EnableFruit.class);
}
}

四、通过继承 ClassPathBeanDefinitionScanner 实现扫描器

在 Spring 体系中,ClassPathBeanDefinitionScanner 占有很重要的地位,如果要实现无 xml 化,就需要注解,有注解就需要自动扫描器。

package org.rockcode.scanner;

import org.rockcode.annotations.EnableFruit;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.type.filter.AnnotationTypeFilter; public class MyClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner { public MyClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry){
super(registry,false);
} public void registerTypeFilter(){
addIncludeFilter(new AnnotationTypeFilter(EnableFruit.class));
} public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
MyClassPathBeanDefinitionScanner myClassPathBeanDefinitionScanner = new MyClassPathBeanDefinitionScanner(context);
myClassPathBeanDefinitionScanner.registerTypeFilter();
myClassPathBeanDefinitionScanner.scan("org.rockcode.services");
// 启动容器,也就是将扫描到的class实例化,并注册到beanFactory中,存入beanDefinitionMap
context.refresh();
//这里会拿到所有的bean实例
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(context.getBean(beanDefinitionName));
}
}
}

最新文章

  1. BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding
  2. Manacher
  3. SAP大数据为&quot;海上F1&quot;提供技术支持
  4. Appium移动自动化测试(四)--先跑起来再说(第一个测试用例-手机YY)
  5. Android开发之旅:环境搭建及HelloWorld
  6. first集合及follow集合
  7. 浅谈KMP算法及其next[]数组
  8. 加密传输SSL协议8_Apache服务器的安装
  9. Android下pm 命令详解
  10. java 小程序开发PKCS7Padding 解密方法实现,以及错误Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法
  11. 20165206 2017-2018-2《Java程序设计》课程总结
  12. &quot;远程服务器返回错误: (500) 内部服务器错误&quot;错误处理
  13. vim命令记录
  14. wamp下var_dump()相关问题
  15. Hbase记录-HBase基本操作(一)
  16. linux命令--文件查询
  17. java基础篇---I/O技术(二)
  18. (原创)使用mceusb设备,将lirc移植到android笔记
  19. dhroid - Perference
  20. Python多线程应用示例

热门文章

  1. tp3.2框架关闭日志记录
  2. python中使用anaconda对不平衡数据的处理包imblearn的安装
  3. zabbix4.2配置监控nginx服务
  4. pytest学习3-断言
  5. 金蝶云星空使用WebAPI来新增单据
  6. java fastjson:Map与json以及JSONObject ,JSONObject与String互转
  7. ET框架之自写模块SmartTimerModule
  8. 函数match应打印s中从ch1到ch2之间的所有字符,并且返回ch1的地址。
  9. util之Queue
  10. TCP/IP详解,卷1:协议--链 路 层