起源:
Java刚开始没有现在这么火,Java成功的今天,完全是因为Spring的全部系列,和独有的反射机制。
起初,所有的对象都要new(),当项目越堆越大时,问题来了。
于是有了工厂模式,需要什么对象,就进行使用工厂进行生产。
后来,人们觉得,虽然对象的耦合度低了,但是,工厂的耦合度又高了。
最终,我们生产出一套机制,利用反射进行
getFields与getDeclareFields的区别:
在书写框架时,我们如果使用getDeclareFields,只能拿到类中所有成员,而不能拿到父类的
在使用getFields的时候,我们可以都拿到
解决方案:(递归打印)
public static void printAllFields(Class clazz){ Field[] fields=clazz.getDeclaredFields(); System.out.println(Arrays.toString(fields)); if(!clazz.getSuperclass().equals(Object.class)){ printAllFields(clazz.getSuperclass()); } }
手写一个注入:
public class UserController { private UserService userService; public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; }}
//用代码进行注入userService
@Test public void testField() throws Exception { UserController userController=new UserController(); Class clazz=userController.getClass();// Field[] declaredFields=clazz.getDeclaredFields();// Arrays.asList(declaredFields).stream().forEach(System.out::println); Field userServiceField=clazz.getDeclaredField("userService"); UserService userService=new UserService(); userServiceField.setAccessible(true); userServiceField.set(userController,userService); //获取get,set的名字 String name=userServiceField.getName(); name=name.substring(0,1).toUpperCase()+name.substring(1,name.length()); String getMethodName="get"+name; String setMethodName="set"+name; Method method=clazz.getMethod(setMethodName,UserService.class); //在userController注入userService method.invoke(userController,userService); System.out.println(userController.getUserService()); }
//使用注解进行注入
package littlepage.test;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface Autowired {}
//开始注入
package littlepage.test;import org.junit.Test;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.util.Arrays;import java.util.stream.Stream;public class DemoTest { @Test public void testField() throws Exception { UserController userController=new UserController(); Class clazz=userController.getClass(); Stream.of(clazz.getDeclaredFields()).forEach(field->{ String name=field.getName(); Autowired annotation=field.getAnnotation(Autowired.class); if(annotation!=null){ field.setAccessible(true); Class type=field.getType(); try { /** * 这个对象直接newInstance出来的 * 在spring中这个bean是定义在注解或者xml中的,如何找到? */ Object object=type.getConstructor(null).newInstance(); field.set(userController,object); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } }); }}
碎觉!明天再刷