Spring 核心技术 IOC ( inversion of control ) OR DI ( Dependency Injection )
这两个我理解应该是同一个意思,只是从不同的角度来解释而已。
1. IOC && DI
给出一个例子:
1.1 非IOC的情况:
class B{ class A{
A a = new A(); A(){
public void fun(){ }
a.fun(); public void fun(){
//do something.
} }
} }
B的行为完全由自己控制,它需要一个具体的A,来做fun这件事情。
1.2 IOC的例子


package com.test;
class B{
@Autowired
IA a;
public void fun(){
a.fun();
}
}
interface IA{
void fun();
}
class AImp implements IA{
public void fun(){
//Do something
}
}
<bean id="testB" class=”com.test.B”>
<property name="testA" ref="testA"></property>
</bean>
<bean id="testA" class="com.test.AImp"></bean>
可以看出控制权由原来的B反转到了外部的配置文件,这也就是所谓的控制反转。
从另外一个角度理解,这个IAImp被B所使用的过程类似于医学上的注射,并且由于IA是B的一个属性,那么根据SPring的角度,IA是B的一个依赖。
2. Spring的流程
在没有Spring的架构时,我们所有的类并没有什么特别的地方,只是简单的POJO。
但是引入Spring之后,首先在启动Context的时候,实例化一个Spring的容器来封装所有的POJO。
而封装这些POJO的依据就是所谓的元数据的这种东西(元数据本身并没有什么实际的工作,而只是为将来实际的工作提供数据的支持)
POJO + Metadata + Spring Container =====> 设定好可使用的Spring系统。
3. 配置元数据的方法
3.1 通过spring的配置文件
<bean id="" class="">
<property name="name" value="some" ></property>
</bean>
强调这里只是配置了元数据,并没有真正的把上述class的一个变量属性值设置为some,这个动作是通过spring的容器来完成。
3.2 通过注解的方式来提供元数据
pacage com.test.metadata;
@Repository("hello")
class Hello{
}
public class InsertHello{
@Autowried
public Hello hello;
}
<context:component-scan base-package="com.test.metadata" />
如上文的代码块,通过注解的方式添加元数据
3.3 通过定义注解Java代码实现(没有研究,我觉得通过上文的注解就已经够我的日常使用了)
4. 实例化Bean
Default: 默认的实例化的方式是,当实例化Spring的容器时,对配置文件中配置的,或者是注解注解的所有元数据表示的Bean进行预先的单例实例化。
可以通过使用延迟加载的机制来避免初次启动Spring应用过慢的问题。该延迟加载可以写入配置文件 lazy="true" ,或者加入注解中。
4.1 通过构造器实例化Bean
该方法是Spring 容器默认的构造方法,即调用相应的构造方法。
4.2 通过静态工厂方法来实例化Bean
该方法必须在配置文件中进行进一步的配置,<bean id="" factory-method=”“></bean>


package com.test;
public class staticFactoryInstance{
private staticFactoryInstance(){
}
public staticFactoryInstance createInstance(){
return new staticFactoryInstance();
}
}
4.3 通过实例方法,但是必须借助非自身bean来进行实例化
该方法必须在配置文件中额外进行定义 <bean id="" factory-bean="" factory-method="" ></bean>
即使用指定的bean的成员方法进行bean的实例化。这里就不写代码实现了,也是相当容易理解的。
5. Bean的视图角度
必备的几个属性:
class: 实例化该Bean的全路径class。
可选的属性:
id/name: 制定引用该Bean的凭据,如果该Bean不会被其他的Bean所依赖,那么可以放弃该属性。
id: 在Spring 3.1 前不能包含特殊的字符,而只是xsi:id的type,仅包含有限的字符集
在Spring 3.2 后属性的type信息已经修正成为String. 所以可以包含特殊的信息
name: 和id的属性功能大致相同,但是会在引用时使用(ref、bean、local)等引用时体现差别。
比较典型的bean的设置为
<bean id="" class="" >
<property name="" value="" ></property>
<property name="" bean/ref/local="" ></property>
<property name="" >
<props> (<list>、<set> etc )
<prop key="" ></prop>
</props>
</property>
</bean>