spring中依赖注入的原理
Spring 从核心而言,是一个DI 容器,其设计哲学是提供一种无侵入式的高扩展性框架。即无需代码中涉及Spring专有类,即可将其纳入Spring容器进行管理。
作为对比,EJB则是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须 遵从。侵入性的后果就是,一旦系统基于侵入性框架设计开发,那么之后任何脱离这个框架的企图都将付 出极大的代价。
为了避免这种情况,实现无侵入性的目标。Spring 大量引入了Java 的Reflection机制,通过动态 调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件BeanFactory,以此作为其依赖注入机制的实现基础。
org.springframework.beans包中包括了这些核心组件的实现类,核心中的核心为BeanWrapper 和BeanFactory类。这两个类从技术角度而言并不复杂,但对于Spring 框架而言,却是关键所在。
InputStream is = new FileInputStream("bean.xml"); XmlBeanFactory factory = new XmlBeanFactory(is); Action action = (Action) factory.getBean("TheAction");
此时获得的Action实例,由BeanFactory进行加载,并根据配置文件进行了初始化和属性设定。
联合上面关于BeanWrapper的内容,可以看到,BeanWrapper实现了针对单个Bean的属性设 定操作。而BeanFactory则是针对多个Bean的管理容器,根据给定的配置文件,BeanFactory从中读取 类名、属性名/值,然后通过Reflection机制进行Bean加载和属性设定。
为student实例,注入nameString
public class reflect
{
public static void main(String[] args)
{
student s = new student();
Class cl = s.getClass();
try
{
java.lang.reflect.Method m = cl.getMethod("setNameString", new Class[]{String.class});
m.invoke(s, "zhangsan");
System.out.println(s.getNameString());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class student
{
private String nameString;
public String getNameString() {
return nameString;
}
public void setNameString(String nameString) {
this.nameString = nameString;
}
}