聊聊、Spring自动扫描
2024-09-06 23:30:54
一、项目
二、自定义注解
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));
}
}
}
最新文章
- BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding
- Manacher
- SAP大数据为";海上F1";提供技术支持
- Appium移动自动化测试(四)--先跑起来再说(第一个测试用例-手机YY)
- Android开发之旅:环境搭建及HelloWorld
- first集合及follow集合
- 浅谈KMP算法及其next[]数组
- 加密传输SSL协议8_Apache服务器的安装
- Android下pm 命令详解
- java 小程序开发PKCS7Padding 解密方法实现,以及错误Cannot find any provider supporting AES/CBC/PKCS7Padding 解决办法
- 20165206 2017-2018-2《Java程序设计》课程总结
- ";远程服务器返回错误: (500) 内部服务器错误";错误处理
- vim命令记录
- wamp下var_dump()相关问题
- Hbase记录-HBase基本操作(一)
- linux命令--文件查询
- java基础篇---I/O技术(二)
- (原创)使用mceusb设备,将lirc移植到android笔记
- dhroid - Perference
- Python多线程应用示例