前言:本次测试目的使用反射方式去赋值一个类的属性,模仿spring注入原理,进一步加深spring,IOC的实现方式理解。
一、普通方式赋值类属性
- 定义一个userService类
public class UserService {
private TestService testService;
public TestService getTestService() {
return testService;
}
public void setTestService(TestService testService) {
this.testService = testService;
}
}
- 定义一个注入的属性testservice
public class TestService {
}
- 写一个test测试类测试,如果getTestService成功能把对象地址打印出来证明对象注入成功,完成测试。
public class ExamTest {
public static void main(String[] args) throws Exception {
// 获取当前对象
UserService userService = new UserService();
Class usercla = userService.getClass();
// 创建属性对象
TestService testService = new TestService();
//获取对象的属性
Field field =usercla.getDeclaredField("testService");
//设置可访问
field.setAccessible(true);
//拼接method名字
String name =field.getName();
name =name.substring(0,1).toUpperCase()+name.substring(1,name.length());
String methodName="set"+name;
//调用setTestService方法
Method method =usercla.getMethod(methodName,TestService.class);
//完成属性注入
method.invoke(userService,testService);
System.out.println(userService.getTestService());
}
}
- 输出结果如图
二、自定义注解方式赋值类属性
- 定义一个autowire注解
//编译期运行
@Retention(RetentionPolicy.RUNTIME)
//作用域是属性
@Target(ElementType.FIELD)
public @interface Autowire {
}
- 给userService加上注解
public class UserService {
@Autowire
private TestService testService;
public TestService getTestService() {
return testService;
}
public void setTestService(TestService testService) {
this.testService = testService;
}
}
- 新建一个测试类,并且判断注解完成注入。
public class ExamTest1 {
public static void main(String[] args) throws Exception {
// 获取当前对象
UserService userService = new UserService();
Class usercla = userService.getClass();
// 创建属性对象
TestService testService = new TestService();
Field[] fields=usercla.getDeclaredFields();
//循环获取对象的属性
for (Field f:fields
) {
Autowire an =f.getAnnotation(Autowire.class);
//判断属性是否加上了注解
if(an!=null){
f.setAccessible(true);
//实例化一个对象使用构造方法
Class type= f.getType();
Constructor c= type.getConstructor();
Object o= c.newInstance();
//对对象进行属性的注入。
f.set(userService,o);
}
}
//输出属性的地址值,证明已经给对象注入了属性
System.out.println(userService.getTestService());
}
}
- 最后输出结果截图
总结:使用了两种方式注入属性,模拟spring注入过程,第二种方式不用自己构造setmethod方法,可以直接自己生成属性注入,更方便灵敏。