最近公司须要,项目中要用到Spring和Ibatis。趁着过年好好学习学习。Ibatis就如同Hibernate同样的持久层技术,学习起来难度不大,但Spring可不同,揣着Ioc,DJ和AOP,四处走红。学起来可不容易。就市面上而言,就一本《expert one-on-one J2EE Development without EJB中文版》值得参考,为了生活,再贵也得买。这本书的前五章都是说EJB的不是,从第六章开始进入正题,介绍控制反转,之后基本都是说Spring了。html
可能本人比较愚笨,控制反转弄得不明白。这样就得上网上找答案了。最后在一个叫Bromon的blog上找到的浅显易懂的答案。下面就是引用他说的话:java
IoC与DIspring
首先想说说IoC(Inversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来讲,就是由spring来负责控制对象的生命周期和 对象间的关系。这是什么意思呢,举个简单的例子,咱们是如何找女友的?常见的状况是,咱们处处去看哪里有长得漂亮身材又好的mm,而后打听她们的兴趣爱 好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,而后嘿嘿……这个过程是复杂深奥的,咱们必须本身设计和面对每一个环节。传 统的程序开发也是如此,在一个对象中,若是要使用另外的对象,就必须获得它(本身new一个,或者从JNDI中查询一个),使用完以后还要将对象销毁(比 如Connection等),对象始终会和其余的接口或类藕合起来。数据库
那么IoC是如何作的呢?有点像经过婚介找女友,在我和女友之间引入了一个第三者:婚姻介绍所。婚介管理了不少男男女女的资料,我能够向婚 介提出一个列表,告诉它我想找个什么样的女友,好比长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,而后婚介就会按照我 们的要求,提供一个mm,咱们只须要去和她谈恋爱、结婚就好了。简单明了,若是婚介给咱们的人选不符合要求,咱们就会抛出异常。整个过程再也不由我本身控 制,而是有婚介这样一个相似容器的机构来控制。Spring所倡导的开发方式就是如此,全部的类都会在spring容器中登记,告诉spring你是个什 么东西,你须要什么东西,而后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其余须要你的东西。全部的类的建立、销毁都由 spring来控制,也就是说控制对象生存周期的再也不是引用它的对象,而是spring。对于某个具体的对象而言,之前是它控制其余对象,如今是全部对象 都被spring控制,因此这叫控制反转。若是你还不明白的话,我决定放弃。apache
IoC的一个重点是在系统运行中,动态的向某个对象提供它所须要的其余对象。这一点是经过DI(Dependency Injection,依赖注入)来实现的。好比对象A须要操做数据库,之前咱们老是要在A中本身编写代码来得到一个Connection对象,有了 spring咱们就只须要告诉spring,A中须要一个Connection,至于这个Connection怎么构造,什么时候构造,A不须要知道。在系统 运行时,spring会在适当的时候制造一个Connection,而后像打针同样,注射到A当中,这样就完成了对各个对象之间关系的控制。A须要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3以后一个重要特征是反射(reflection),它容许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是经过反射来实现注入的。关于反射的相关资料请查阅java doc。编程
我想经过Bromon的介绍,你们对IoC和DI都有了比较生动的理解了。再来看看《expert one-on-one J2EE Development without EJB中文版》是怎么解释这两个概念的。书上是这么说的:app
IoC是一个很大的概念,能够用不一样的方式来实现。主要的实现形式有两种:框架
依赖查找:容器提供回调接口和上下文环境给组件。EJB和Apache Avalon都是使用这种方式。eclipse
依赖注入:组件不作定位查询,只是提供普通的Java方法让容器去决定依赖关系。容器全权负责组件的装配,它会把符合依赖关系的对象经过JavaBean属性或者构造子传递给须要的对象。经过JavaBean属性注射依赖关系的作法称为设值方法注入(Setter Injection);将依赖关系做为构造子参数传入的作法称为构造子注入(Constructor Injection)。学习
附图说明:

到这里,你们应该对IoC与DI都有了初步的认识了。其实就Spring来讲,就是JavaBean由Spring来管理组装,表面上看就少了几个new字,其实就是为了下降耦合度,这也是咱们作软件的目标之一。
至于Spring是怎样实现IoC的,《expert one-on-one J2EE Development without EJB中文版》第七章“Spring框架介绍”很详细的列举了多种方法。说实在,一会儿看这么多,我真有点糊涂了。我仍是本身写个Demo熟悉一下大名鼎鼎的Spring吧。
首先得下载Spring。Spring网上有两种Spring包一种是spring-framework-1.2.6-with-dependencies.zip,另外一种是spring-framework-1.2.6.zip。固然最好是下载spring-framework-1.2.6-with-dependencies.zip形式的,由于里面包括了更多的东东。spring-framework-1.2.6-with-dependencies.zip的下载地址是:http://prdownloads.sourceforge.net/springframework/spring-framework-1.2.6-with-dependencies.zip。
下载下来,解压后,你会发现里面有不少jar文件。由于刚刚接触Spring,所以我只须要spring-core.jar(spring-framework-1.2.6\dist),将其导入eclipse的构建路径中。另外,log日志是须要的,这也是为了养成良好的编程习惯。将log4j-1.2.9.jar(spring-framework-1.2.6\lib\log4j)和commons-logging.jar(spring-framework-1.2.6\lib\jakarta-commons)导入到构建路径中。
准备就绪,开始写Demo了。
个人工程的结构是:
一、 log4j.properties代码:
log4j.rootLogger
=
Debug, stdout
log4j.appender.stdout
=
org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout
=
org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern
=%
c{
1
}
-
%
m
%
n
如何使用Log4j,请看个人另外一篇转贴的文章:如何使用Log4J。
二、 HelloBean的代码:
package
com;
public
class
HelloBean {
private
String helloworld
=
"
Hello!World!
"
;
public
String getHelloworld() {
return
helloworld;
}
public
void
setHelloworld(String helloworld) {
this
.helloworld
=
helloworld;
}
}
这是一个简单的JavaBean,有个String类型的helloworld属性,初始值是"Hello!World!"。
三、 Bean.xml代码:
<?
xml version
=
"
1.0
"
encoding
=
"
GBK
"
?>
<!
DOCTYPE beans PUBLIC
"
-//SPRING/DTD BEAN/EN
"
"
http://www.springframework.org/dtd/spring-beans.dtd
"
>
<
beans
>
<
bean id
=
"
helloBean
"
class
=
"
com.HelloBean
"
>
<
property name
=
"
helloworld
"
>
<
value
>
Hello
!
Rick
</
value
>
</
property
>
</
bean
>
</
beans
>
Spirng重点之一就是配置文件,上面是个至关简单的配置文件,我想你们都应该看得懂。最后就是写应用程序了。
四、 Test的代码:
package
com;
import
org.springframework.beans.factory.
*
;
import
org.springframework.beans.factory.xml.XmlBeanFactory;
import
org.springframework.core.io.ClassPathResource;
import
org.springframework.core.io.Resource;
public
class
Test {
public
static
void
main(String[] args) {
//
实例化JavaBean,主要是为了比较new对象和依赖注入二者的区别
HelloBean hellobean
=
new
HelloBean();
System.out.println(hellobean.getHelloworld());
//
经过Spring访问JavaBean组件
Resource resource
=
new
ClassPathResource(
"
com/bean.xml
"
);
BeanFactory factory
=
new
XmlBeanFactory(resource);
hellobean
=
(HelloBean)factory.getBean(
"
helloBean
"
);
System.out.println(hellobean.getHelloworld());
}
}
这个Demo很好的阐述了Spring的Ioc,其实就Spring而言,就是经过配置文件,让Spring如同一个管家同样来管理全部的Bean类。
Spring的依赖注入相对复杂一点,主要是明白调用别的Bean,不是经过实例化对象来调用,而是告诉Spring,我须要什么Bean,而后Spring再向你的Bean里面注入你所须要的Bean对象。
接下来讲说代码实现,我只是在刚刚的例子上再添加一点东东。
首先要增长一个HelloImp的接口,这是问什么呢,那你得问Spring,它定的规矩:JavaBean的实现要有两个部分,一个接口,一个默认实现。你不照作就不行。
HelloImp代码:
package
com;
public
interface
HelloImp {
public
void
getName();
}
实现HelloImp的Hello代码:
package
com;
public
class
Hello
implements
HelloImp {
public
void
getName(){
System.out.println(
"
Jack
"
);
}
}
接着就是在
HelloBean
中调用
Hello
了。
Spring
的不一样之处也在这体现出来。
package
com;
public
class
HelloBean {
private
String helloworld
=
"
Hello!World!
"
;
private HelloImp hello; //注意这个私有对象是借口
public
String getHelloworld() {
return
helloworld;
}
public
void
setHelloworld(String helloworld) {
this
.helloworld
=
helloworld;
}
public void setHello(HelloImp hello) {
this.hello = hello;
}
public void get(){
this
.hello.getName();
}
}
注意字体加粗的地方。
配置文件也须要增长一点东西:
<?
xml version
=
"
1.0
"
encoding
=
"
GBK
"
?>
<!
DOCTYPE beans PUBLIC
"
-//SPRING/DTD BEAN/EN
"
"
http://www.springframework.org/dtd/spring-beans.dtd
"
>
<
beans
>
<!
—注意引用的类是具体的类Hello
-->
<
bean id
=
"
myHello
"
class
=
"
com.Hello
"
>
</
bean
>
<
bean id
=
"
helloBean
"
class
=
"
com.HelloBean
"
>
<
property name
=
"
helloworld
"
>
<
value
>
Hello
!
Rick
</
value
>
</
property
>
<property name="hello">
<ref bean="myHello"></ref>
</property>
</
bean
>
</
beans
>
注意字体加粗的部分。
最后在
Test
中添加一句
hellobean.get();
就能够看到结果了。
package
com;
import
org.springframework.beans.factory.
*
;
import
org.springframework.beans.factory.xml.XmlBeanFactory;
import
org.springframework.core.io.ClassPathResource;
import
org.springframework.core.io.Resource;
public
class
Test {
public
static
void
main(String[] args) {
HelloBean hellobean
=
new
HelloBean();
System.out.println(hellobean.getHelloworld());
Resource resource
=
new
ClassPathResource(
"
com/bean.xml
"
);
BeanFactory factory
=
new
XmlBeanFactory(resource);
hellobean
=
(HelloBean)factory.getBean(
"
helloBean
"
);
System.out.println(hellobean.getHelloworld());
hellobean.get(); } }
到这,Spring的IoC和DI总算有了必定的认识,也算是敲开了Spring的大门了。