做告状网站,网站改版公告,济南市莱芜区网站,什么网站可以自己做名片学习材料
尚硅谷Spring零基础入门到进阶#xff0c;一套搞定spring6全套视频教程#xff08;源码级讲解#xff09;
有关反射的知识回顾
IoC是基于反射机制实现的。 Java反射机制是在运行状态中#xff0c;对于任意一个类#xff0c;都能够知道这个类的所有属性和方法一套搞定spring6全套视频教程源码级讲解
有关反射的知识回顾
IoC是基于反射机制实现的。 Java反射机制是在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意方法和属性这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。简单来说反射机制指的是程序在运行时能够获取自身的信息。 要想解剖一个类必须先要获取到该类的Class对象。而剖析一个类或用反射解决具体的问题就是使用相关API1java.lang.Class2java.lang.reflect所以Class对象是反射的根源。 具体要掌握的操作就是如何获取class三种方法如何获取构造器及创建对象如何获取属性如何获取方法并执行。这里注意public和private的不同操作。
package com.zy.reflect;import org.testng.annotations.Test;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;public class TestCar {Testpublic void test01() throws Exception {//获取class的方法
// Car car new Car();
// Class clazz1 car.getClass();Class clazz2 Car.class;Class clazz3 Class.forName(com.zy.reflect.Car);Constructor[] constructors clazz3.getDeclaredConstructors();for(Constructor con:constructors){if(con.getParameterCount()3){con.setAccessible(true);Car car (Car) con.newInstance(奔驰, 1, 黑色);
// System.out.println(car);}}//或者直接获取Constructor c2 clazz3.getDeclaredConstructor(String.class, Integer.class, String.class);c2.setAccessible(true);Car car2 (Car)c2.newInstance(捷达, 15, 白色);System.out.println(car2);}Testpublic void test02() throws Exception {Class clazz3 Class.forName(com.zy.reflect.Car);Car car (Car)clazz3.getConstructor().newInstance();Field[] fields clazz3.getDeclaredFields();for (Field field:fields) {if(field.getName().equals(name)) {//设置允许访问field.setAccessible(true);field.set(car,五菱宏光);//这里需要有对应的对象。System.out.println(car);}System.out.println(field.getName());}}Testpublic void test03() throws Exception {Class clazz3 Class.forName(com.zy.reflect.Car);Car car (Car)clazz3.getConstructor().newInstance();Method[] methods clazz3.getDeclaredMethods();for (Method method:methods) {//执行方法 toStringif(method.getName().equals(toString)) {String invoke (String)method.invoke(car);System.out.println(toString执行了invoke);}if(method.getName().equals(run)) {//设置允许访问method.setAccessible(true);method.invoke(car);//这里需要有对应的对象。System.out.println(car);}}}
}
手写IoC
实现的思路设计 环境框架
第一二步手打过很多次了没什么难度。 第三步 创建Annotation文件与接口之类的类似。不同在于有元注解需要考虑注解面向的范围Bean是创建类Di注入
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
public interface Bean {
}Target({ElementType.FIELD})
Retention(RetentionPolicy.RUNTIME)
public interface Di {
}第四步要了解这一步要干嘛需要从需求出发。 需求如下即输入一个com.zy。我要组织得到一个Map集合创建好所有标注注解Bean的类与Di注入。getBean用于利用class信息返回Map内的元素。
public class TestUser {public static void main(String[] args) {ApplicationContext context new AnnotationApplicationContext(com.zy);UserService bean (UserService)context.getBean(UserService.class);bean.add();}
}如何实现创建Map主要学习的是如何遍历文件如何扫描注解
private MapClass, Object beanFactory new HashMap();private static String rootPath;Overridepublic Object getBean(Class clazz) {return beanFactory.get(clazz);}
public AnnotationApplicationContext(String basePackage) {//如何根据包的路径设置扫描规则try {String packageDirName basePackage.replaceAll(\\., \\\\);EnumerationURL dirs Thread.currentThread().getContextClassLoader().getResources(packageDirName);while (dirs.hasMoreElements()) {URL url dirs.nextElement();String filePath URLDecoder.decode(url.getFile(),utf-8);
// System.out.println(filePath);//包扫描rootPath filePath.substring(0, filePath.length()-packageDirName.length());loadBean(new File(filePath));}} catch (Exception e) {throw new RuntimeException(e);}//属性注入loadDi();}private void loadBean(File file) throws Exception {//1.当前FIle是否是文件夹if (file.isDirectory()){//2.是文件夹的话获取所有内容File[] childrenFiles file.listFiles();//3.判断内容是否为空if (childrenFiles null || childrenFiles.length0){return;}//4.遍历所有内容for (File child:childrenFiles){//1.还是文件夹就递归if (child.isDirectory()){loadBean(child);}else {//是文件获取完整的类路径String pathWithClass child.getAbsolutePath().substring(rootPath.length()-1);//是不是class文件if (pathWithClass.contains(.class)){String allName pathWithClass.replaceAll(\\\\, \\.).replace(.class, );//判断类中有没有Bean注解Class? clazz Class.forName(allName);if (!clazz.isInterface()){Bean annotation (Bean)clazz.getAnnotation(Bean.class);if (annotation!null){Object instance clazz.getConstructor().newInstance();if (clazz.getInterfaces().length0){beanFactory.put(clazz.getInterfaces()[0], instance);}else{beanFactory.put(clazz, instance);}}}}}}}}private void loadDi(){//实例化对象在beanFactory的map//1 遍历beanFactory的mapSetMap.EntryClass, Object entries beanFactory.entrySet();for(Map.EntryClass, Object entry:entries){//2 获取map的每个对象value每个对象属性获取到Object obj entry.getValue();Class clazz obj.getClass();Field[] fields clazz.getDeclaredFields();//3 遍历得到每个对象属性数组得到每个属性for(Field field:fields){//4 判断属性上面是都有Di注解Di annotation field.getAnnotation(Di.class);//5 如果有Di注解把对象进行设置注入if (annotation!null){field.setAccessible(true);//这一步什么filed这个属性的类型field.getType() beanFactory.get()得到对应的对象。try {field.set(obj, beanFactory.get(field.getType()));} catch (IllegalAccessException e) {throw new RuntimeException(e);}}}}