聊聊、Spring自动扫描
一、项目

二、自定义注解
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));
}
}
}
聊聊、Spring自动扫描的更多相关文章
- spring自动扫描、DispatcherServlet初始化流程、spring控制器Controller 过程剖析
spring自动扫描1.自动扫描解析器ComponentScanBeanDefinitionParser,从doScan开始扫描解析指定包路径下的类注解信息并注册到工厂容器中. 2.进入后findCa ...
- Spring、Spring自动扫描和管理Bean
Spring2.5为我们引入了组件自动扫描机制,它可以在类路径下寻找标记了@Component.@Service.@Controller.@Repository注解的类,并把这些类纳入到spring容 ...
- 从架构演进的角度聊聊Spring Cloud都做了些什么?
Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...
- 聊聊 Spring Boot 2.x 那些事儿
本文目录: 即将的 Spring 2.0 - Spring 2.0 是什么 - 开发环境和 IDE - 使用 Spring Initializr 快速入门 Starter 组件 - Web:REST ...
- 朱晔和你聊Spring系列S1E1:聊聊Spring家族的几大件
朱晔和你聊Spring系列S1E1:聊聊Spring家族的几大件 [下载本文PDF进行阅读] Spring家族很庞大,从最早先出现的服务于企业级程序开发的Core.安全方面的Security.到后来的 ...
- 从架构演进的角度聊聊Spring Cloud都做了些什么
1.从架构演进的角度聊聊Spring Cloud都做了些什么?2.中小型互联网公司微服务实践-经验和教训3.Spring Cloud在国内中小型公司能用起来吗?
- Spring自动扫描无法扫描jar包中bean的解决方法(转)
转载自:http://www.jb51.net/article/116357.htm 在日常开发中往往会对公共的模块打包发布,然后调用公共包的内容.然而,最近对公司的公共模块进行整理发布后.sprin ...
- 聊聊 Spring Boot 2.0 的 WebFlux
聊聊 Spring Boot 2.0 的 WebFlux## 前言 对照下 Spring Web MVC ,Spring Web MVC 是基于 Servlet API 和 Servlet 容器设计的 ...
- (转)让Spring自动扫描和管理Bean
http://blog.csdn.net/yerenyuan_pku/article/details/52861403 前面的例子我们都是使用XML的bean定义来配置组件.在一个稍大的项目中,通常会 ...
- 【小家Spring】聊聊Spring中的数据绑定 --- BeanWrapper以及内省Introspector和PropertyDescriptor
#### 每篇一句 > 千古以来要饭的没有要早饭的,知道为什么吗? #### 相关阅读 [[小家Spring]聊聊Spring中的数据转换:Converter.ConversionService ...
随机推荐
- 题解【AcWing271】杨老师的照相排列
题面 经典的线性 \(\text{DP}\) . 设 \(dp_{a,b,c,d,e}\) 表示第 \(1\) 排有 \(a\) 个人,第 \(2\) 排有 \(b\) 个人, 第 \(3\) 排有 ...
- IE浏览器复选框遍历不兼容问题
obj = document.getElementsByName("userIdCheckbox"); ids = []; for(var k=0;k<obj.length; ...
- adb 无线连接手机设备
连接语法: $ adb connect ip:port 断开连接: $ adb disconnect ip:port 可能遇到问题:unable to connect to 192.168.199.2 ...
- SQL语句分类和语法
DQL:Data QueryLanguage 数据查询语言 作用: 查询表中的字段 命令: select 查询 ⑦select 查询列表①from 表1 别名②连接类型 joi ...
- Asp.net的WebForm的落后技术
本文链接:https://bbs.csdn.net/topics/392077893 因为webform确实,企图通过在html标签中的runat="server",在iis接受请 ...
- AcWing 803. 区间合并
#include <iostream> #include <vector> #include <algorithm> using namespace std; ty ...
- python修改文件后缀名
修改文件后缀名 # -*- coding: utf-8 -*- import os # # 列出当前目录下所有的文件 # filedir = 'C:\\Users\\WT\\Desktop\\test ...
- eclipse非正常关闭,再打开后报错
Previous operation has not finished; run 'cleanup' if it was interrupted 启动任务管理器,将javaw.exe进程杀死,然后重启 ...
- 2019牛客多校第四场K number dp or 思维
number 题意 给一个数字串,问有几个子串是300的倍数 分析 dp写法:这题一看就很dp,直接一个状态dp[i][j]在第i位的时候膜300的余数是j左过去即可.这题比赛的时候样例老是少1,后面 ...
- js的一些基础
事件对象: 就是用来存储事件相关的信息 事件对象存储信息有: 事件的类别,如:click,keydown等等 点击事件的位置 点击的哪一个键 等等 用于阻止事件流,用于阻止浏览器默认动作(表单提交.a ...