. java 反射
Java
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java
语言的反射机制。简单来说,反射机制指的是程序在运行时能够获取自身的信息。
要想解剖一个类,必须先要获取到该类的Class对象。而剖析一个类或用反射解决具体的问题就是使用相关API**(1)java.lang.Class(2)java.lang.reflect**,所以,Class对象是反射的根源。
手写IOC
package Bean; import org.springframework.context.annotation.Bean; import javax.print.DocFlavor; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.net.URLEncoder; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; public class AnnApplicationContextIMPL implements ApplicationContext{ /*创建map防止bean对象*/ private Map<Class,Object> beanfactory=new HashMap<>(); private static String rootPath; @Override public Object GetBean(Class clazz) { return beanfactory.get(clazz); } //设置包扫描规则 //当前包 及其子包 如果有注解 就通过反射进行实例化 public AnnApplicationContextIMPL(String basePackage){ //public static void pathdemo1(String basePackage){ try { //1.把里面的。换成\ String PackagePath= basePackage.replaceAll("\\.","\\\\"); //2.获取包的绝对路径 Enumeration urls= Thread.currentThread().getContextClassLoader().getResources(PackagePath); while (urls.hasMoreElements()){ URL url= (URL) urls.nextElement(); String filePath= URLEncoder.encode(url.getFile(),"utf-8"); System.out.println("filePath = " + filePath); //获取包相对路径 截取 rootPath=filePath.substring(0,filePath.length()-basePackage.length()); //包扫描 leanBean(new File(filePath)); } } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } } //包扫描的过程 private void leanBean(File file) throws ClassNotFoundException { //1.判断当前内容是不是文件夹 if (file.isDirectory()){ //2.获取文件夹的所有内容 包括子文件夹 File[] childrenfile=file.listFiles(); //3.判断是否为空 if (childrenfile==null||childrenfile.length==0){ return; } //4.如果不为空 遍历所有内容 for (File child:childrenfile){ //4.1.遍历每个file对象,继续判断是否为空,递归。 if (child.isDirectory()){ leanBean(child); }else { //4.2.得到的flie如果不是文件夹,是文件。. //4.3.得到包路径+类名称-----即是字符串截取 String pathWithClass = child.getAbsolutePath().substring(rootPath.length()-1); //4.4.判断当前文件类型 是否是.class类型 if (pathWithClass.contains(".class")){ //4.5.如果是.class类型 如果是 把路径\替换成. 把.class去掉 String allName=pathWithClass.replaceAll("\\\\","."). replace(".class",""); //4.6.判断类上是否有注解@bean,如果有进行实例化 //4.6.1 获取类的class 对象 Class<?> clazz = Class.forName(allName); //4.6.2判断是不是接口 if(clazz.isInterface()){ //判断上面是否有注解@ Bean annotation = clazz.getAnnotation(Bean.class); if (annotation!=null){ try { Object instance = clazz.getConstructor().newInstance(); //4.7把实例化之后的内容 放入Map //4.7.1 判断当前类是否有接口 让class作为map的类 if (clazz.getInterfaces().length>0){ beanfactory.put(clazz.getInterfaces()[0],instance); }else{ beanfactory.put(clazz,instance); } } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } } } } } } } } }