反射
String——>类——>对象
设计一个方法 给你一个字符串(包名加类名) 返回一个对象 对象里面还有属性值
我们之前做过的 考试系统的Question类 银行系统Person类
Question类和Person类都是自己定义的 这两个类的目的仅仅是为了存储某些信息
看似是个对象 更像是个容器 ——> 实体domain
传递一个字符串 帮我们创建对象 这样就不用自己创建 同时还能给对向内的所有属性赋值
——> Spring开源框架 IOC控制反转 DI依赖注入
AOP面向切面
IOC控制反转 Inversion of Control 对象的控制权反转
DI依赖注入 Dependency Injection 对象的控制权是别人的 别人在创建对象的同时 帮我们自动的注入属性值
DI是IOC的一个具体体现 需要先把控制权交给别人 如果别人做的好 可能才会帮你注入属性值 但是也可以不注入 所以DI的前提是先有IOC
自定义注解MyAnnotation:
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.CONSTRUCTOR})@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation {String[] value();}
Person类:
public class Person {private String name;private Integer age;private String sex;@MyAnnotation({"小兰","18","女"})public Person(){}public void setName(String name){this.name = name;}public void setAge(Integer age){this.age = age;}public void setSex(String sex){this.sex = sex;}public String getName(){return this.name;}public Integer getAge(){return this.age;}public String getSex(){return this.sex;}}
MySpring:
public class MySpring {//设计一个方法 给一个类名 返回一个对象 并给这个对象属性赋值public Object getBean(String className){Object obj = null;try {//1.获取路径上所对应的类Class clazz = Class.forName(className);//2.获取类所对应的无参数构造方法 前提得有构造方法Constructor con = clazz.getConstructor();//3.通过构造方法得到当前类的对象obj = con.newInstance();//4.获取构造方法上对应的注解对象Annotation ma = (MyAnnotation)con.getAnnotation(MyAnnotation.class);//5.获取注解对象对应的类Class mClazz = ma.getClass();//6.获取注解对象里的value方法Method m = mClazz.getMethod("value");//7.执行value方法 并接收注解信息 注意value方法是属于注解的String[] values = (String[]) m.invoke(ma);//8.获取类中的全部的私有属性Field[] fields = clazz.getDeclaredFields();//9.构造出set+属性名的方法 并 运行给属性赋值for(int i = 0;i<fields.length;i++){//9.构造出set+属性名的方法 并 运行给属性赋值//9.1 属性名首字母大写String firstLetter = fields[i].getName().substring(0,1).toUpperCase();String otherLetters = fields[i].getName().substring(1);//9.2 利用StringBuilder拼接方法名StringBuilder setMethodName = new StringBuilder("set");setMethodName.append(firstLetter);setMethodName.append(otherLetters);//10.因为属性的方法需要传与属性类型相对应的参数类型 所以获取方法的参数类型 即获取属性的类型Class fieldType = fields[i].getType();//11.通过 拼接好的属性方法名 以及 方法参数类型 找到类中对应的set方法Method fieldMethod = clazz.getMethod(setMethodName.toString(),fieldType);//12.执行set方法 并 给方法传参 参数即为注解里的信息//但是获取到的values信息都是String类型的 而属性不一定都是String类型的//所以 需要将 String--->属性对应的类型//fieldType.getConstructor(String.class).newInstance(values[i]) 利用这个构造方法来创建对象//即先找到属性类型对应的构造方法 这个构造方法中有带String参数的// (八个包装类中只有Character没有带String类型的构造方法 所以可以单独判断)fieldMethod.invoke(obj,fieldType.getConstructor(String.class).newInstance(values[i]));}} catch (Exception e) {e.printStackTrace();}return obj;}}
主方法:
public static void main(String[] args) {MySpring ms = new MySpring();Person p = (Person) ms.getBean("test_annotation.Person");//包名加类名System.out.println(p.getName()+"--"+p.getAge()+"--"+p.getSex());}
