关于什么是Ioc这篇博客说的很清楚了,但也有一些不足的地方,就是Spring的IoC容器是使用了反射机制和工厂模式。
再理解Ioc具体原理之前,先理解一下Java反射机制.
通过反射机制可以实现上层类对下层类的"控制"(无论是函数、私有的属性都可以访问)。
使用反射机制来实现Controller层访问Service层
Controller层
public class UserController {
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
实现Controller层注入Service
public static void main(String[] args) throws Exception {
UserController controller=new UserController();
/**通过对象.getClass来获取映射对象
* */
Class<? extends UserController> clazz=controller.getClass();
/**给Controller中的UserService中的
* 对象赋值
* */
UserService service=new UserService();
/**获取映射对象的属性
* 通过调用映射对象的get函数来获取
* */
Field field=clazz.getDeclaredField("userService");
/**设置属性的访问权限
* */
field.setAccessible(true);
/**通过set函数来注入
* */
String name=field.getName();
name=name.substring(0,1).toUpperCase()+name.substring(1);
String setMethod="set"+name;
Method method=clazz.getMethod(setMethod,UserService.class);
/**反射
* */
method.invoke(controller,service);
System.out.println("Controller层获取到的对象: "+controller.getUserService());
System.out.println("new出来的对象: "+service);
}
运行结果:
实现@AutoWrited注解
注解
@Retention(RetentionPolicy.RUNTIME) //设置当前注解使用范围:源码,编译,运行时
@Target(ElementType.FIELD) //当前注解作用再属性上
public @interface AutoWrite {
}
Controller层
public class UserController {
@AutoWrite
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
}
实现:
public static void main(String[] args) throws Exception {
UserController controller=new UserController();
Class<? extends UserController> clazz=controller.getClass();
/**获取所有属性值
* */
Stream.of(clazz.getDeclaredFields()).forEach(field -> {
/**获取注解
* */
AutoWrite autoWrite= field.getAnnotation(AutoWrite.class);
if(autoWrite!=null){
field.setAccessible(true);
/**获取属性的类型
* */
Class<?>type=field.getType();
try {
Object o=type.newInstance();
field.set(controller,o);
} catch (IllegalAccessException |
InstantiationException e) {
e.printStackTrace();
}
}
});
System.out.println("注入的Service对象 "+controller.getUserService());
}
运行结果:
Spring底层原理初步理解
Spring提供的扩展性:
1、在创建对象之前添加某些功能
2、在容器初始化之前添加某些功能
3、抽象出一堆接口来帮助扩展
4、在不同阶段发出不同的事件