Spring基础5——自定义反射创建实例和@Autowired注解的工作原理
一、自定义反射创建实例
利用setter()函数反射注入实例
- 通过反射的方式,要注入某个实例的class
package xxx.xxx.controller;
import xxx.xxx.service.UserService;
/**
* Created by xxx on 2020/9/11
*/
public class UserController {
//在UserController中注入UserService
private UserService userService;
public UserService getUserService() {
return userService;
}
//必须要有属性的setter方法
public void setUserService(UserService userService) {
this.userService = userService;
}
}
- 被注入的class
package xxx.xxx.service;
/**
* Created by xxx on 2020/9/11
*/
public class UserService {
}
- 利用反射注入实例:
import xxx.xxx.controller.UserController;
import xxx.xxx.service.UserService;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class IocTest {
@Test
public void reflectInjectInstance() throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
UserController userController = new UserController();
Class<? extends UserController> clazz = userController.getClass();
UserService userService = new UserService();
//获取名字叫userService的所有属性
Field field = clazz.getDeclaredField("userService");
//通过setter方法设置具体的属性值
String fieldName = field.getName();
fieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length());
String setName = "set" + fieldName;
//通过方法注入属性的对象
Method method = clazz.getMethod(setName, UserService.class);
//反射
method.invoke(userController, userService);
//比较反射注入的对象与原对象是否相同
System.out.println(userController.getUserService() == userService);
}
}
上述代码的执行结果,如下所示:

二、自定义@Autowired注解反射注入实例
Spring的@Autowired注解也是通过反射的方式注入实例的,通过自定义@Autowired注解的方式可以还原Spring的@Autowired注解注入实例的核心过程,代码如下:
- 自定义@Autowired注解
package xxx.xxx.controller;
import java.lang.annotation.*;
/**
* Created by xxx on 2020/9/13
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
@Documented
public @interface Autowired {
}
- 通过反射的方式,要注入某个实例的class
package xxx.xxx.controller;
import xxx.xxx.service.UserService;
/**
* Created by xxx on 2020/9/11
*/
public class UserController {
//在UserController中注入UserService
@Autowired
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public String toString() {
return "UserController{" +
"userService=" + userService +
'}';
}
}
- 被注入的class
package xxx.xxx.service;
/**
* Created by xxx on 2020/9/11
*/
public class UserService {
}
- 利用反射向带有@Autowired注解的变量注入实例:
import org.junit.Test;
import xxx.xxx.controller.Autowired;
import xxx.xxx.controller.UserController;
import xxx.xxx.service.UserService;
import org.junit.Test;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class IocTest {
@Test
public void annotationInjectInstance() {
UserController userController = new UserController();
Class<? extends UserController> clazz = userController.getClass();
//获取所有属性,进行遍历。
for (Field field : clazz.getDeclaredFields()) {
//获取属性上的Autowired注解。
Autowired annotation = field.getAnnotation(Autowired.class);
if (annotation != null) {
//存在标记了@Autowired注解的属性,获取该属性的类型,并且实例化一个该类型的对象。
field.setAccessible(true);
Class<?> type = field.getType();
try {
Object o = type.newInstance();
//通过field.set(),将实例化好的对象赋值
field.set(userController, o);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
System.out.println(userController.getUserService());
}
}
上述代码的执行结果,如下所示:


浙公网安备 33010602011771号