1.咱們看到@ComponentScan註解一個開始定義就是須要支持,掃描多個包,將多個包的類名獲取到。如今就實現這個功能。數組
根據傳入的字符串數組,得到多個包下的類全限制名。函數
--基於以前的代碼--測試
1.在PackageUtils.增長一個掃描多個包的方法this
1 /** 2 * 支持同時掃描多個包的路徑下的類全限制名以及其子包的全部類的全限制名 包名直接使用逗號分割 3 * 4 * @param packageNames:傳入多個包名 5 * @param isRecursion:是否掃描包的子包 6 * @return 返回因此掃描到類全限制名 7 */ 8 public static Set<String> getClassNames(String[] packageNames, boolean isRecursion) { 9 //1.建立一個Set集合將每一個包下的類放在一塊兒。 10 Set<String> classNamesSet=new HashSet<String>(); 11 // 數值的長度 12 int length = packageNames.length; 13 for (int i = 0; i < length; i++) { 14 Set<String> classNameSet = PackageUtils.getClassName(packageNames[i], isRecursion); 15 //每次都將包放在總的Set集合中 16 classNamesSet.addAll(classNameSet); 17 } 18 return classNamesSet; 19 }
2.修改AbstractApplicationContext的構造函數,標紅處spa
1 public AbstractApplicationContext(Class<?> classType) { 2 //判斷配置類是否有Configuration註解 3 Configuration annotation = classType.getAnnotation(Configuration.class); 4 if(annotation!=null){ 5 //得到組件掃描註解 6 ComponentScan componentScan = classType.getDeclaredAnnotation(ComponentScan.class); 7 //得到包名 8 this.basePackage = componentScan.basePackages(); 9 //根據包名得到類全限制名 10 //Set<String> classNames = PackageUtils.getClassName(this.basePackage[0], true); 11 //將掃描一個包,修改成多個包 12 Set<String> classNames = PackageUtils.getClassNames(this.basePackage, true); 13 //經過類名建立對象 14 Iterator<String> iteratorClassName = classNames.iterator(); 15 while(iteratorClassName.hasNext()){ 16 String className = iteratorClassName.next(); 17 try { 18 //經過類全名建立對象 19 Object instance = Class.forName(className).newInstance(); 20 //將對象加到容器中,對象名就類全名 21 this.getContext().addObject(instance.getClass().getSimpleName(),instance); 22 } catch (InstantiationException e) { 23 e.printStackTrace(); 24 } catch (IllegalAccessException e) { 25 e.printStackTrace(); 26 } catch (ClassNotFoundException e) { 27 e.printStackTrace(); 28 } 29 } 30 } 31 }
1.Config類-,掃描ioc.core.test.config包和ioc.core.test.service包code
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.測試類,輸出容器中的對象component
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.測試結果,將兩個包的類的對象都放在了容器裏面。成功。對象