获取指定路径,扫描路径下指定类(仿Spring)

本文目标:传入指定路径,扫描对应路径下符合要求的类,并添加到指定的集合中。


其原型是Spring中初始化容器类的一部分。当然本例仅仅完成基本功能,没有考虑过多功能——即Spring中配置对应的CompontScan路径,并在类上添加@Component注解,即可完成将一个类添加到Spring容器。




自定义两个注解(2个):类比理解Spring中@Component、@ComponentScan注解

自定义MobianContext容器类(1个):类比理解Spring中AnnotationConfigApplicationContext

自定义MobianBeanDefinition类(1个):类比理解Spring中的BeanDefinition

自定义MobianConfig配置类(1个):类比理解Spring中的我们自己自定义的配置类




1、文件整体目录结构

请添加图片描述




2、自定义注解

这两个注解仅有最基础的功能,且必须配置对应的value值

MobianScan的value用于配置扫描路径

MobianComponent的value用来配置类的别名

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MobianScan {
	String value();
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MobianComponent {
	String value();
}




3、编写被测试对象类

随便写的几个类,部门类添加指定的注解,并且配置别名信息

@MobianComponent("teacher")
public class TeacherService {
}
public class StudentService {
}
public interface SchoolService {
	void show();
}
@MobianComponent("schoolService")
public class SchoolServiceImpl implements  SchoolService {

	@Override
	public void show() {
	}
}




4、编写一个配置类

初始化context容器时使用

其创建是为了模仿spring的配置类,本例中仅需要使用配置的路径

@MobianScan("pers.imitationspring.service")
public class MobianConfig {
}




5、编写BeanDefinition类

这里的作用和Spring中对应的类作用相同,用来存放所有Bean的初始化信息,只是本例中比较简单

public class MobianBeanDefinition {
	private Class clazz;

	public Class getClazz() {return clazz;}
	public void setClazz(Class clazz) {this.clazz = clazz;}
}




6、编写容器类(重点)

具体细节以在代码中给出注释,主要步骤分为以下几步:

  1. 解析传入配置类上@MobianComponentScan注解配置的包路径
  2. 将包路径转化为url路径
  3. 根据url路径定位到具体的文件位置,完成文件夹下文件的遍历
  4. 将具体文件的文件位置,转化为类加载能够识别的包路径
  5. 使用类加载器加载具体的,此时可以完成类的加载
  6. 解析类上的@MobianComponent配置的类的别名信息
  7. 将类的别名信息以及类信息存储到beanDefinitionMap中
public class MobianContext {

	// 存放所有扫描出来的Bean,等价于Spring中的beanDefinitionMap集合
	ConcurrentHashMap<String, MobianBeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

	public MobianContext(Class config) throws ClassNotFoundException {

		if (config.isAnnotationPresent(MobianScan.class)) {
			MobianScan scanAnno = (MobianScan) config.getAnnotation(MobianScan.class);
			// 获取注解中配置的路径
			String scanPath = scanAnno.value();

			// 将对应的路径转化为路径格式
			String scanUrl = scanPath.replace(".", "/");

			// 通过类加载器,传入相对于当前项目的路径(target/classes目录下),查找指定的资源
			// scanUrl:pers/imitationspring/service
            ClassLoader loader = MobianContext.class.getClassLoader();
			URL resource = loader.getResource(scanUrl);

			// resource : file:/E:/Softwareworkspace/ideaworkspace/writespring/target/classes/pers/imitationspring/service
			if (resource != null) {
				// 获取对应路径资源下的所有文件
				File files = new File(resource.getFile());

				// 遍历对应的文件
				for (File file : files.listFiles()) {

					// 获取当前文件的绝对路径
					String path = file.getAbsolutePath();
					// 切割路径字符串,拿到相对路径
					String classPath = path.substring(path.indexOf("pers"), path.indexOf(".class"));
					// 将相对路径转换为包结构
					classPath = classPath.replace("\\", ".");

					// 根据类的路径去创建一个对象,此时已经能获取到对应的类信息
					Class<?> aClass = loader.loadClass(classPath);
					System.out.println(aClass);
					// 获取类上对应的注解
					MobianComponent componentAnno = aClass.getAnnotation(MobianComponent.class);
					if (componentAnno != null) {
						// 在Component注解不为空的情况下,获取注解内的信息(即类注册的别名)
						String beanName = componentAnno.value();
						MobianBeanDefinition beanDefinition = new MobianBeanDefinition();
						beanDefinition.setClazz(aClass);
						// 将类别名和类信息存储到beanDefinitionMap中
						beanDefinitionMap.put(beanName, beanDefinition);
					}
				}
			}
		}
	}


	// 获取beanDefinitionMap集合中存储的所用信息
	public void printBeanDefinitionMap() {
		for (Map.Entry<String, MobianBeanDefinition> bd : beanDefinitionMap.entrySet()) {
			System.out.println(bd.getKey() + " : " + bd.getValue().getClazz());
		}
	}
}




7、测试类

初始化Context容器类,打印beanDefinitionMap集合内容(所有满足要求的类)

public class Test {
	public static void main(String[] args) throws ClassNotFoundException {

		MobianContext context = new MobianContext(MobianConfig.class);
		System.out.println("====");
		context.printBeanDefinitionMap();
	}
}

测试结果:

请添加图片描述



即我们配置的扫描路径下面包含3个类1个接口,但是符合要求的(@MobianComponent)类只有2个,满足要求的类的别名分别时teacher和是schoolService。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MyBatis 目录(?)[-] mybatis实战教程mybatis in action之一开发环境搭建 mybatis实战教程mybatis in action之二以接口的方式编程 mybatis实战教程mybatis in action之三实现数据的增删改查 mybatis实战教程mybatis in action之四实现关联数据的查询 mybatis实战教程mybatis in action之五与spring3集成附源码 mybatis实战教程mybatis in action之六与Spring MVC 的集成 mybatis实战教程mybatis in action之七实现mybatis分页源码下载 mybatis实战教程mybatis in action之八mybatis 动态sql语句 mybatis实战教程mybatis in action之九mybatis 代码生成工具的使用 mybatis SqlSessionDaoSupport的使用附代码下载 转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过Hibernate了那这个就非常的简单) (再加一条,其实大家可以看官方的教程更好些:http://mybatis.github.io/mybatis-3/,而且如果英文不是很好的那就看中文的:http://mybatis.github.io/mybatis-3/zh/sqlmap-xml.html) 写在这个系列前面的话: 以前曾经用过ibatis,这是mybatis的前身,当时在做项目时,感觉很不错,比hibernate灵活。性能也比hibernate好。而且也比较轻量级,因为当时在项目中,没来的及做很很多笔记。后来项目结束了,我也没写总结文档。已经过去好久了。但最近突然又对这个ORM 工具感兴趣。因为接下来自己的项目中很有可能采用这个ORM工具。所以在此重新温习了一下 mybatis, 因此就有了这个系列的 mybatis 教程. 什么是mybatis MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. orm工具的基本思想 无论是用过的hibernate,mybatis,你都可以法相他们有一个共同点: 1. 从配置文件(通常是XML配置文件中)得到 sessionfactory. 2. 由sessionfactory 产生 session 3. 在session 中完成对数据的增删改查和事务提交等. 4. 在用完之后关闭session 。 5. 在java 对象和 数据库之间有做mapping 的配置文件,也通常是xml 文件。 mybatis实战教程(mybatis in action)之一:开发环境搭建 mybatis 的开发环境搭建,选择: eclipse j2ee 版本,mysql 5.1 ,jdk 1.7,mybatis3.2.0.jar包。这些软件工具均可以到各自的官方网站上下载。 首先建立一个名字为 MyBaits 的 dynamic web project 1. 现阶段,你可以直接建立java 工程,但一般都是开发web项目,这个系列教程最后也是web的,所以一开始就建立web工程。 2. 将 mybatis-3.2.0-SNAPSHOT.jar,mysql-connector-java-5.1.22-bin.jar 拷贝到 web工程的lib目录. 3. 创建mysql 测试数据库和用户表,注意,这里采用的是 utf-8 编码 创建用户表,并插入一条测试数据 程序代码 程序代码 Create TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userName` varchar(50) DEFAULT NULL, `userAge` int(11) DEFAULT NULL, `userAddress` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; Insert INTO `user` VALUES ('1', 'summer', '100', 'shanghai,pudong'

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默辨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值