原生的在xml注解代码为
<context:component-scan base-package="com.ymt.spring.component"/>
package com.ymt.spring.Annoationex; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ComponentScan { String value() default ""; }
这个value指定要扫描的包 作用类似component-scan
package com.ymt.spring.annoation; //这是一个配置类。作用类似我们原生的spring的beans.xml容器配置文件 @ComponentScan(value = "com.ymt.spring.component") public class HspSpringConfig { }
如何将生成的对象放入到容器之中
package com.ymt.spring.Annoationex; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; import java.io.File; import java.net.URL; import java.util.concurrent.ConcurrentHashMap; //YmtSpringApplicationContext类的作用类似spring原生ipc容器 public class YmtSpringApplicationContext { private Class configClass; //ioc存放的就是通过反射创建的对象(基于注解方式) private final ConcurrentHashMap<String,Object> ioc=new ConcurrentHashMap<>(); public YmtSpringApplicationContext(Class configClass){ this.configClass=configClass; System.out.println("this.configClass="+this.configClass); //获取要扫描的包 //1.@ComponentScan(value = "com.ymt.spring.component")先得到 ComponentScan componentScan = (ComponentScan) this.configClass.getDeclaredAnnotation(ComponentScan.class); String path = componentScan.value(); System.out.println("path="+path); //得到要扫描的包下的所有资源(.class) //1.先得到类的加载器 ClassLoader classLoader = this.configClass.getClassLoader(); //2.通过类的加载器获取到要扫描的包的资源url URL resource = classLoader.getResource("com/ymt/spring/component"); System.out.println(resource); File file = new File(resource.getFile()); System.out.println(path); //3.将要加载的资源(.class)路径下的文件进行遍历=>io if (file.isDirectory()){ File[] files = file.listFiles(); for (File f : files) { // System.out.println("======="); // System.out.println(f.getAbsolutePath()); String fileabsolutePath = f.getAbsolutePath(); //3.判断该。class是不是需要注入到容器中 例如要有注解 if (fileabsolutePath.endsWith(".class")){ String className = fileabsolutePath.substring(fileabsolutePath.lastIndexOf("\\") + 1, fileabsolutePath.indexOf(".class")); // System.out.println(className); String classFullName=path+"."+className; try { //这时得到该类的全类名 Class<?> aClass = classLoader.loadClass(classFullName); // System.out.println(aClass); if (aClass.isAnnotationPresent(Component.class)||aClass.isAnnotationPresent(Controller.class)||aClass.isAnnotationPresent(Service.class)||aClass.isAnnotationPresent(Repository.class)){ //这时就可以反射对象,并返入到容器中 Class<?> aClazz= Class.forName(classFullName); Object instance = aClazz.newInstance(); ioc.put(className,instance); } } catch (Exception e) { e.printStackTrace(); } } } } } }