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);
    }
}

上述代码的执行结果,如下所示:
clipboard

二、自定义@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());
    }
}

上述代码的执行结果,如下所示:
image

posted @ 2025-12-21 10:46  Carey_ccl  阅读(2)  评论(0)    收藏  举报