目录
往userController中自动注入userService
往userController中自动注入userService
public class UserController{
@Autowired
private UserService userService;
}
普通反射的方式
package com.spring;
import com.spring.controller.UserController;
import com.spring.service.UserService;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class MyTest {
//@Test
public void test() throws Exception {
UserController userController = new UserController();
Class<? extends UserController> clazz = userController.getClass();
//创建对象
UserService userService = new UserService();
//获取属性值
Field serviceField = clazz.getDeclaredField("userService");
//因为属性值是私有的,只能通过set方法和get方法设置和获取值,所以需要先拿到属性名然后拼接成对应的方法
String name = serviceField.getName();
//拼接方法的名称
name = name.substring(0,1).toUpperCase() + name.substring(1, name.length());
String setMethodName = "set" + name;
//通过方法注入属性的对象
Method method = clazz.getMethod(setMethodName, UserService.class);
//反射
method.invoke(userController, userService);
System.out.println(userController.getUserService());
}
}
通过一系列的反射操作将userService属性注入至userController之中。实际以上的原生代理在实际工作中都用注解进行代替。
只要获取了一个对象的class对象,就可以为这个类做随意的编写。(属性,构造器,方法啊等等)
注解的方式-未利用到set
自己实现一个@AutoWired注解
package com.spring.annotation;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
@Documented
public @interface AutoWired {
}
package com.spring;
import com.spring.annotation.AutoWired;
import com.spring.controller.UserController;
import com.spring.service.UserService;
import java.util.stream.Stream;
public class MyTest2 {
public static void main(String[] args) {
UserController userController = new UserController();
Class<? extends UserController> clazz = userController.getClass();
UserService userService = new UserService();
//获取所有的属性值
Stream.of(clazz.getDeclaredFields()).forEach(field -> {
String name = field.getName();
AutoWired annotation = field.getAnnotation(AutoWired.class);
//表示当前属性上加了注解
if(annotation != null){
field.setAccessible(true);
//获取属性的类型(userService对应的类型为UserService)
Class<?> type = field.getType();
//根据获取到的类型new一个实例对象
try {
Object o = type.newInstance();
//把创建的对象注入至属性中
field.set(userController, o);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
});
System.out.println(userController.getUserService());
}
}
和上面的代码对比,无拼接set方法的步骤,而是利用得到的属性类型创建了一个UserService对象再设置至属性中去,不是我们自己去创建的。没有用到和set相关的东西。
类似地@Value @Controller @Component @Service都可以作类似的实现
Spring整体脉络梳理
学习建议:一定要去看官网
beanFactory:一个接口,一定存在对应的实现类。
DefaultListableBeanFactory.java中存在很多的Map(可以认为IOC容器中就是创建了很多的Map集合)