聊聊、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 ...
随机推荐
- centos7安装启动firefox
1.卸载系统之前Firefox sudo yum erase firefox 2.安装firefox命令: sudo yum install firefox 3.驱动下载地址: https://git ...
- c#字符串常用方法
一.字符串常用方法 1.IndexOf("") 如果找到字符串出现的位置则为索引位置,否则返回-1,索引从0开始 2.string Substring( int sta ...
- SpringMVC请求乱码问题
今天做一个项目实现插入数据的功能,最开始没有添加FilterEncoding处理字符集乱码了,那是正常的,后来我添加过之后依然还是乱码,让我 百思不得其解,代码配置如下: EncodingFilter ...
- Radar Installation(利用数据有序化进行贪心选择)
English appre: an infinite straight line:一条无限长的直线 on the coasting:在海岸线上 Cartesian coordinate system, ...
- 创建一个Java Web项目,获取POST数据并显示
新建一个新的Java Web工程项目 打开IntelliJ IDEA 新建一个工程,选择选择Java Enterprise,设置Tomcat的安装目录,点击下一步. 选中Create project ...
- 02-Java基础语法【数据类型转换、运算符、方法入门】
重点知识记录 01.数据类型转换 当数据类型不一样是,将会发生数据类型转换. 1)自动类型转换(隐式): 特点:代码不需要进行特殊处理,自动完成: 规则:数据范围从小到大:byte < shor ...
- Java连载77-Integer常用方法、Integer、int、String三者相互转化、自动装箱、自动拆箱
一.关于Integer中常用的方法 package com.bjpowernode.java_learning; public class D77_1_ { public static void ...
- http请求常见错误状态码
一.HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求.不作修改,客户程序就无法重复此请求. 原因:(调用方接口方法的实参和服务器接口方法的形参不一致) 1.前端提交数据 ...
- python之路之网络基础
c类地址
- wireshark抓pc上的包
简介:wirkshark是全世界最广泛的网络封包分析软件之一. 软件用途: 网络管理员:我用它检测网络问题, 网络安全工程师:我用它检查资讯安全相关问题, 开发者:我用它为新的通讯协定除错, 普通使用 ...