Java反射机制概述
作为Java高级属性,Java反射机制将类中的各个组成部分封装为其他对象,这就是反射机制。
好处:
可以在程序运行过程中操作这些对象。
可以解耦,提高程序的可扩展性。
获取Class对象的方式
- Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象。
多用于配置文件,将类名定义在配置文件中。读取文件,加载类 - 类名.class:通过类名的属性class获取。
多用于参数的传递 - 对象.getClass():getClass()方法在Object类中定义着。
多用于对象的获取字节码的方式。
Spring IOC
控制反转-Inversion Of Control
1、对象存哪去? 分析:由于我们是很多对象,肯定要找个集合来存。这时候有 Map 和 List 供选择。 到底选 Map 还是 List 就看我们有没有查找需求。有查找需求,选 Map。 所以我们的答案就是 在应用加载时,创建一个 Map,用于存放三层对象。 我们把这个 map 称之为容器。
2、还是没解释什么是工厂? 工厂就是负责给我们从容器中获取指定对象的类。这时候我们获取对象的方式发生了改变。
原来:我们在获取对象时,都是采用 new 的方式。是主动的。
现在:我们获取对象时,同时跟工厂要,有工厂为我们查找或者创建对象。是被动的。
Spring IOC基础Java反射机制
接下来通过程序来展示一下,Java反射机制在Spring IOC中的应用。
package com.instance.service;
public class UserService {
}
package com.instance.controller;
import com.instance.service.UserService;
public class UserController {
UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
```java
package com.instance;
import com.instance.controller.UserController;
import com.instance.service.UserService;
import org.junit.Test;
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();
System.out.println(userService);
//获取所有的属性
Field serviceField = clazz.getDeclaredField("userService");
//如果UserController中有私有属性可以通过设置以下语句来获取属性
serviceField.setAccessible(true);
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());
}
}
通过打印的两个相同的对象,说明Java反射机制实现了:
public void setUserService(UserService userService) {
this.userService = userService;
}
接着,Java反射机制实现注解@AutoWired :
package com.instance.controller;
import com.instance.AutoWired;
import com.instance.service.UserService;
public class UserController {
@AutoWired
UserService userService;
public UserService getUserService() {
return userService;
}
/**
* @AutoWired
* UserService userService;
* 等效于下面的代码块
* public void setUserService(UserService userService) {
* this.userService = userService;
* }
*/
}
package com.instance;
import java.lang.annotation.*;
/**
* 自定义@AutoWoired 注解来实现其注入功能。
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited
@Documented
public @interface AutoWired {
}
package com.instance;
import com.instance.controller.UserController;
import org.junit.Test;
import java.util.stream.Stream;
/**
* 此代码中可以很好的阐释,Spring IOC的基础是Java反射机制。
*/
public class MyTest1 {
@Test
public void test(){
UserController userController = new UserController();
Class<? extends UserController> clazz = userController.getClass();
//获取所有的属性值
Stream.of(clazz.getDeclaredFields()).forEach(field ->{
AutoWired autoWired = field.getAnnotation(AutoWired.class);
if(autoWired != null){
field.setAccessible(true);
//获取属性的类型
Class<?> type = field.getType();
try{
Object o = type.newInstance();
field.set(userController,o);
}catch(Exception e){
e.printStackTrace();
}
}
});
System.out.println(userController.getUserService());
}
}