实现功能

1.我们看到@ComponentScan注解一个开始定义就是需要支持,扫描多个包,将多个包的类名获取到。现在就实现这个功能。

实现思路

根据传入的字符串数组,获得多个包下的类全限制名。

实现步骤

--基于之前的代码--

1.在PackageUtils.增加一个扫描多个包的方法

     /**
* 支持同时扫描多个包的路径下的类全限制名以及其子包的所有类的全限制名 包名直接使用逗号分割
*
* @param packageNames:传入多个包名
* @param isRecursion:是否扫描包的子包
* @return 返回所以扫描到类全限制名
*/
public static Set<String> getClassNames(String[] packageNames, boolean isRecursion) {
//1.创建一个Set集合将每个包下的类放在一起。
Set<String> classNamesSet=new HashSet<String>();
// 数值的长度
int length = packageNames.length;
for (int i = 0; i < length; i++) {
Set<String> classNameSet = PackageUtils.getClassName(packageNames[i], isRecursion);
//每次都将包放在总的Set集合中
classNamesSet.addAll(classNameSet);
}
return classNamesSet;
}

2.修改AbstractApplicationContext的构造函数,标红处

     public AbstractApplicationContext(Class<?> classType) {
//判断配置类是否有Configuration注解
Configuration annotation = classType.getAnnotation(Configuration.class);
if(annotation!=null){
//获得组件扫描注解
ComponentScan componentScan = classType.getDeclaredAnnotation(ComponentScan.class);
//获得包名
this.basePackage = componentScan.basePackages();
//根据包名获得类全限制名
//Set<String> classNames = PackageUtils.getClassName(this.basePackage[0], true);
11 //将扫描一个包,修改为多个包
12 Set<String> classNames = PackageUtils.getClassNames(this.basePackage, true);
//通过类名创建对象
Iterator<String> iteratorClassName = classNames.iterator();
while(iteratorClassName.hasNext()){
String className = iteratorClassName.next();
try {
//通过类全名创建对象
Object instance = Class.forName(className).newInstance();
//将对象加到容器中,对象名就类全名
this.getContext().addObject(instance.getClass().getSimpleName(),instance);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}

测试代码

1.Config类-,扫描ioc.core.test.config包和ioc.core.test.service包

package ioc.core.test.config;

import ioc.core.annotation.ComponentScan;
import ioc.core.annotation.Configuration; //使用定义@Configuration定义该类是一个配置类
@Configuration
//使用ComponentScan设置扫描包的路径
@ComponentScan(basePackages={"ioc.core.test.config","ioc.core.test.service"})
public class Config { }

2.测试类,输出容器中的对象

package ioc.core.test;

import org.junit.Test;

import ioc.core.impl.AnntationApplicationContext;
import ioc.core.test.config.Config;
public class AnntationApplicationContextTest { @Test
public void login(){
try {
AnntationApplicationContext context=new AnntationApplicationContext(Config.class);
System.out.println(context.getContext().getObjects()); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

3.测试结果,将两个包的类的对象都放在了容器里面。成功。

一起写框架-Ioc内核容器的实现-基础功能-ComponentScan支持多包扫描(六)的更多相关文章

  1. 一起写框架-Ioc内核容器的实现-基础功能-ComponentScan支持组件注解限制(七)

    实现功能 以上的代码我们发现.我们都是将@ComponentScan扫描的路径下的所有类都加载到容器中的. 而实际需求,我们并不希望所有的类都创建对象,而是加了组件注解@Controller,@Ser ...

  2. 一起写框架-Ioc内核容器的实现-基础功能-ComponentScan(四)

    功能说明 该步骤实现的功能包括: 1. 启动程序时,将@ComponentScan加载的类,创建对象并放在容器里面. 2. 通过ApplicatoinContext的getBean()方法获得容器里面 ...

  3. 一起写框架-Ioc内核容器的实现-基础功能-容器对象名默认首字母小写(八)

    实现功能 --前面实现的代码-- 默认的对象名就类名.不符合Java的命名规范.我们希望默认的对象名首字母小写. 实现思路 创建一个命名规则的帮助类.实现将对大写开头的对象名修改为小写开头. 实现步骤 ...

  4. 一起写框架-Ioc内核容器的实现-基础功能-getBean(五)

    实现的功能 1. 启动程序时,将@ComponentScan加载的类,创建对象并放在容器里面.(查看上一篇文) 2. 通过ApplicatoinContext的getBean()方法获得容器里面的对象 ...

  5. 一起写框架-Ioc内核容器的实现-基础API的定义(三)

    Ioc内核要解决的问题 1.被调用方,在程序启动时就要创建好对象,放在一个容器里面. 2.调用方使用一个接口或类的引用(不用使用new),就可以创建获得对象. 解决这个两个问题的思路 1.定义一个对象 ...

  6. Spring源码分析-从@ComponentScan注解配置包扫描路径到IoC容器中的BeanDefinition,经历了什么(一)?

    阅前提醒 全文较长,建议沉下心来慢慢阅读,最好是打开Idea,点开Spring源码,跟着下文一步一步阅读,更加便于理解.由于笔者水平优先,编写时间仓促,文中难免会出现一些错误或者不准确的地方,恳请各位 ...

  7. 自己动手写框架——IoC的实现

    先看看 IoC百度百科 优化过程 namespace Test { class Program { static void Main(string[] args) { //场景 某公司客服要回访一些客 ...

  8. 用C写一个web服务器(一) 基础功能

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

  9. spring框架--IOC容器,依赖注入

    思考: 1. 对象创建创建能否写死? 2. 对象创建细节 对象数量 action  多个   [维护成员变量] service 一个   [不需要维护公共变量] dao     一个   [不需要维护 ...

随机推荐

  1. Nexus 私有仓库搭建与 Maven 集成

    Nexus 私有仓库搭建与 Maven 集成 |作者:RexFang |出处:http://www.cnblogs.com/rexfang/ |关于作者:Java 程序员一枚 |版权:本文版权归作者和 ...

  2. hdu3507 Print Article(斜率DP优化)

    Zero has an old printer that doesn't work well sometimes. As it is antique, he still like to use it ...

  3. http://codeforces.com/contest/536/problem/B

    B. Tavas and Malekas time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  4. @htmlhepler dropdownlistfor 报错

    说系统的字段不匹配. 是因为ViewData,没有赋值.

  5. Python实战之Selenium自动化测试web刷新FW

    需求:将手工登录,手工刷新服务器的FW转化为Python+Selenium实现自动化操作. 1.创建用户表,实现数据与脚本分离.需要读取模块. 2.自动化刷新FW. 不说话,直接上代码: 1userd ...

  6. firewalld 操作实践

    1.firewalld 从名称上看,模仿的是硬件防火墙的概念,zone. 所有的接口都必须属于某个zone . 在zone内配置规则. 2.  常用的方法是 增加对一个tcp或者udp端口号的允许通过 ...

  7. 逆波兰表达式(RPN)算法简单实现

    算法分析: 一.预处理 给定任意四则运算的字符串表达式(中缀表达式),preDeal预先转化为对应的字符串数组,其目的在于将操作数和运算符分离. 例如给定四则运算内的中缀表达式: String inf ...

  8. checkValidity-表达验证方法。

    调用该方法,可以显示对表单元素进行有效验证,返回值是boolean. 代码如下: <!DOCTYPE html> <html> <head> <meta ch ...

  9. ftpclient 550 permission denied

    遇到一个坑,ftp服务器有主被动模式,如果ftpclient 没有设置模式,默认就是主动模式,如果ftp服务器是被动模式,那么使用ftpclient就执行上传和下载,就会失败, 添加ftpClient ...

  10. win10 uwp 上传Nuget 让别人用我们的库

    Nuget 我们的开发经常使用别人的dll,那么我们需要每次都从网上下载,然后复制到我们的项目, 而不知道我们的dll是否安全? 当我们的库更新的时候,我们又需要从网上搜索,这样不好,于是我们就用Nu ...