一、DI依赖注入
1.谁依赖谁,为什么需要依赖,谁注入谁,注入了什么?
应用程序依赖IOC容器、需要IOC容器提供对象、IOC注入对象、注入了外部对象
2.常用的3种注入方式?注解注入、setter注入、构造方法注入
二、Ioc控制反转
1.将对象和依赖对象的创建交给Spring容器去管理。由spring来负责控制对象的生命周期和对象间的关系。
2.谁控制谁,控制什么、为何是反转、哪些方面反转了、正转是什么?
Ioc容器控制对象;
控制对象的获取;
容器帮我们查找及注入依赖对象,对象只是被动接受依赖对象;
获取依赖对象被反转了,它是被动获取;
正转就是自己去new一个对象,自己获取对象。
3.为什么要用控制返转,怎么使用IOC反转?
(1)使用传统方式耦合性高
(2)通过注解配置使用IOC(controller、service、dao)
三、Spring IOC实现原理
(1)依赖注入的思想:通过反射机制来实现的,通俗的讲就是根据类名动态生成对象。当在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。
//实例化一个类
public static Object newInstance(String className) {
Class<?> cls = null;
Object obj = null;
try {
cls = Class.forName(className);//取得class对象
obj = cls.newInstance();
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return obj;
}
//Class.forName返回的是一个类。是用到了java.lang.Class.forName包的方法,全称是指包名称加类名称。
是通过jvm来加载的,通过jvm就可以获取到这个类。也可以通过反射来操作这个类,例如获取属性,获取方法。
//将这个类的依赖注入进去
public static void setProperty(Object obj, String name, String value) {
Class<? extends Object> clazz = obj.getClass();
try {
String methodName = returnSetMthodName(name);
Method[] ms = clazz.getMethods();
for (Method m : ms) {
if (m.getName().equals(methodName)) {
if (m.getParameterTypes().length == 1) {
Class<?> clazzParameterType = m.getParameterTypes()[0];
setFieldValue(clazzParameterType.getName(), value, m, obj);
break;
}
}
}
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
最后它将这个类的实例返回给我们,这样就可以用Spring 给我们创建的类。
if(value instanceof Map){
Iterator<?> entryIterator=((Map<?, ?>)value).entrySet().iterator();
Map<String, Object> map=new HashMap<String, Object>();
while(entryIterator.hasNext()){
Entry<?, ?> entryMap=(Entry<?, ?>)entryIterator.next();
if(entryMap.getValue()instanceof String[]){
map.put((String)entryMap.getKey(),getBean(((String[])entryMap.getValue())[0]));
}
}
BeanProcesser.setProperty(obj,property,map);
}