对Spring 框架的学习心得
一、概要介绍
Spring 框架估计大家都已经了解。它的目的是解决企业应用开发的复杂性,在功能上是用基本的JavaBean代替EJB,并提供了更多的企业应用功能。
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式。现在把Spring主要的并且非常基础的IOC与AOP的应用一些心得给大家介绍一下。
1、 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是
BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
2、 Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
这两个方面应该说在Spring中用到的非常广泛。
二、详细介绍
1、IOC的说明
IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
从上图可以看到IOC主要包括两个部分的内容,一个是依赖查找、另外一个是依赖注入两个部分。
依赖查找就是容器提供回调接口和上下文环境给组件,例如EJB就是通过这种JNDI的方式进行上下文查找。示例代码:
InitialContext ctx = new InitialContext();
Object obj = ctx.lookup(EJBProxy.JNDI);
CPTransHome localhome (CPTransHome)PortableRemoteObject.narrow(obj,CPTransHome.class);
依赖查找的主要问题是,这段代码必须依赖于JNDI环境,所以它不能在应用服务器之外运行,并且如果要用别的方式取代JNDI来查找资源和协作对象,就必须把JNDI代码抽出来重构到一个策略方法中去。
依赖注入实现的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。
依赖注入包括接口、设值、构造三种注入方式。
代码示例如下:
待注入的业务对象Content.java
public class Content {
public void BusniessContent(){
System.out.println("do business");
}
public void AnotherBusniessContent(){
System.out.println("do another business");
}
}
构造注入示例:
public class MyBusiness {
private Content myContent;
注:通过构造函数注入对象 public MyBusiness(Content content) {
myContent = content;
}
public void doBusiness(){
myContent.BusniessContent();
}
public void doAnotherBusiness(){
myContent.AnotherBusniessContent();
}
}
设值注入示例:
public class MyBusiness {
private Content myContent;
注:通过set的方式直接注入 public void setContent(Content content) {
myContent = content;
}
public void doBusiness(){
myContent.BusniessContent();
}
public void doAnotherBusiness(){
myContent.AnotherBusniessContent();
}
}
接口注入示例:
设置注入接口:
public interface InCeshi {
void createContent(Content content);
}
接口注入:
public class MyBusiness implements InContent{
private Content myContent;
public void createContent(Content content) {
myContent = content;
}
public void doBusniess(){
myContent.BusniessContent();
}
public void doAnotherBusniess(){
myContent.AnotherBusniessContent();
}
}
Spring核心就是利用了IOC模式的依赖注入原则。依赖注入原则也是Spring实现的重点内容。
同时我们也可以把IOC的依赖注入原则看做是工厂模式的升华,可以把IoC看作是一个工厂,这个工厂里要生成的对象都是在XML文件中给出定义的,然后利用Java的“反射”机制,根据XML中给出的类名生成相应的对象。从实现来看,IoC是把以前在工厂方法里写死的对象生成代码,改变为由XML文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。
Spring利用IOC并结合工厂模式,实现了对象的实例化。IOC容器的载体其实可以理解为就是Map,即我们常说的缓存。在spring中IOC缓存主要分bean实例的缓存(单例)和bean定义信息的缓存,然后通过getBean()得到实例。用到哪个实例得到哪个。
org.springframework.beans.factory.BeanFactory是Spring Ioc容器的真实描述,Spring Ioc容器负责包含并管理所有的bean。
BeanFactory接口是Ioc容器的核心接口,它的职责就是初始化应用程序所需的对象,并配置这些对象、聚合这些对象之间的依赖。
Spring为提供了许多易用的BeanFactory
实现,XmlBeanFactory
就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。XmlBeanFactory
类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
我们可以使用下面的代码实例化BeanFactory:
InputStream is = new FileInputStream("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
或者
ClassPathResource res = new ClassPathResource("beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);
或者
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
// of course, an ApplicationContext is just a BeanFactory
BeanFactory factory = (BeanFactory) appContext;
注:ApplicationContext是整个spring的上下文环境。
以下是一个基于XML的配置元数据的基本结构:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<beans>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here... -->
</beans>
2、AOP的说明
OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决解决问题的方法中的共同点,是对OO思想的一种补充!
面向对象的编程(OOP)方法是在面向过程的编程方法基础上进行的改进,而面向方面编程(AOP)方法又是在面向对象编程(OOP)方法的基础上进行改进而来的一种创新的软件开发方法。AOP和OOP虽然在字面上十分相似,但是却是面向不同领域的两种设计思想。
OOP(面向对象编程)针对问题领域中以及业务处理过程中存在的实体及其属性和操作进行抽象和封装,面向对象的核心概念是纵向结构的,其目的是获得更加清晰高效的逻辑单元划分;
AOP则是针对业务处理过程中的切面进行提取,例如:
某一个操作在各个模块中都有涉及,这个操作就可以看成“横切”存在于系统当中。在许多情况下,这些操作都是与业务逻辑相关性不强或者不属于逻辑操作的必须部分,而面向对象的方法很难对这种情况做出处理。
AOP则将这些操作与业务逻辑分离,使程序员在编写程序时可以专注于业务逻辑的处理,而利用AOP将贯穿于各个模块间的横切关注点自动耦合进来。AOP的核心思想就是将应用程序中的业务逻辑处理部分同对其提供支持的通用服务,即所谓的“横切关注点”进行分离,这些“横切关注点”贯穿了程序中的多个纵向模块的需求。
使用AOP机制进行开发,首先要对方面进行了解,将需求分解成一般关注点和横切关注点,即将核心模块级的关注点和系统级的横切关注点分离;然后各自独立的实现这些关注点;最后用工具将业务逻辑代码和横切关注点代码编织到一起,形成最终的程序。通过面向方面的编程可以减少编码时间和重复。
实现原理:Spring框架中AOP的实现主要是利用java的动态代理机制。
代理分为两种如下所示:
要在Spring中实现AOP,一般情况下需要配置4个bean:
1. 目标对象(target)
2. 通知(advice)
3. 切入点(pointcut)
4. 代理(proxy)
Spring提供的通知类型有:
AfterReturningAdvice, MethodInterceptor,MethodBeforeAdvice,这些都是Spring AOP定义的接口类,具体的动作实现需要用户程序来完成。
其次,在配置文件中配置ProxyFactoryBean。因为Spring是通过ProxyFactoryBean来配置我们的代理对象和方面行为。其属性主要为以下几个:target 目标对象e、proxyInterfaces 代理的接口、interceptorNames 代理要干什么,几部分组成。
由于ProxyFactoryBean是一个FactoryBean,在ProxyFactoryBean中我们通过 getObject()可以直接得到代理对象。
示例配置代码:
<!—以下为创建通知->
<bean id="log" class="dao.LogAround"/>
<!—以下为目标对象->
<bean id="timeBook" class="dao.TimeBook"/>
<!—以下为创建代理->
<!--使用Spring提供的ProxyFactoryBean来实现代理-->
<bean id="logProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>dao.TimeBookInterface</value>
</property>
<!--指定要代理的类-->
<property name="interceptorNames">
<list>
<value>log</value>
</list>
</property>
<!—要产生的目标对象-->
<property name="target">
<ref bean="timeBook"/>
</property>
</bean>
上面所示timeBook就是业务处理类,可以根据具体的业务需要进行编写。而interceptorNames就是需要处理的代理类,通过集成Spring提供的几种通知类型进行处理。
以上是对Spring中的两个比较基础并且非常重要的两个方面做了一下简单的介绍。Spring是一个功能非常强大的框架,它还包含了DAO、MVC、O/R、以及事务处理等非常多的功能。尤其是目前的SSH框架应用率更是非常高。
由于元数据的引入,Spring已经应用到的我们系统中。Spring已经有好多介绍文章,我只是简单的理解了一下、学习一下。希望对大家有点小帮助!
注:后面的两个类图是Spring的IOC实现的类结构图。
第一张是BeanFactory的继承关系,一直到XMLBeanFactory的生成。
第二张是XMLBeanFactory所关联的一些类,主要是对配置文件的解析。希望对研究源码有帮助。
第一张;
第二张:
第二篇:Spring学习心得
Spring学习心得(转)
最近有人问我学习Spring的经验。心中不免有些惭愧,本来以为自己对Spring算比较精通啦,但最近看Professional Java development with
SpringFramework,发现其实自己还有好多东西不知道。不过既然有人问起,就大概谈一下体会吧,由于我自己的途径与下面所列的步骤还是有些差距的(主要是当时关于Spring的书和参考资料太少了),而且每个人的学习方式也会不同,所以只能作为参考了。
一 一、首先Java的基础、面向对象的基础和设计模式的基础知识是必不可少的。
如果连这些基础知道都不够扎实的话,我建议还是先去补补课。关于设计模式我觉得不用学太多,但以下三个模式是学习Spring必不可少的:factory模式(包括简单工厂和抽象工厂),Strategy模式,Template method模式。如果不掌握这些你就根本没法领悟Spring的精髓,只能依样画葫芦地照搬,这是很可怕的事。
关于这方面的书的建议已经够多的,我就不说了。我这里强烈建议的书可能让人有点意外,那就是Expert one on one J2EE design and development的第四章,这一章不仅仅是Spring初学者,而是任何搞Java开发的人必读的一章。经典!
二、接下可以看一些Spring的入门书籍
其实我自己没怎么看过这方面的书,我当时只看过Spring的reference,不过现在这方面的书好象多的是,而Spring reference看起来还是有些吃力的。JavaEye上很多人建议夏昕的Spring开发指南,据说入门很容易。另外的入门书应该是Spring live或Spring in action。我大概扫了一下,Spring live是一本只讲怎么做而不讲为什么的书,我不太喜欢(偶尔参考一下倒不错),不过有些人特别喜欢这样的书,看自己的个人爱好吧。
三、研究几个用Spring做的开源项目
理论还是要与实际结合,所以看完书后是要看实际的项目的。很多人喜欢
appfuse,我觉得appfuse花的东西太多,真正实质性的内容又太少。我更喜欢Spring自带的jpetstore,这是一个非常完整的例子,看完后Spring的基本用法应该都能掌握。
四、开始做实际的项目
在上述这些都完备以后,我觉得应该要去实际项目中锻炼了。当然并不是每人都有这样的机会的,这时只能自己做个玩具项目啦。项目的锻炼是非常关键的,其实每个人都清楚,我就不重复了。
五、继续深入学习
经过项目的锤炼,对Spring的用法和原理有了一定的了解的时候,才有可能真正掌握Spring的精髓。这时要读的书才是Rod Johnson的三本经典名著,分别是:
Expert one on one J2ee design and development
Expert one on one J2ee without EJB
Professional Java Development with SpringFramework
前两本书的经典程度我就不说了,只有读了它们,才能真正了解Spring的设计意图,掌握Spring的精髓。
第三本书是我强烈不建议初学者读的书。里面的东西深入而全,但是原理讲解得又不够深,很容易让初学者犯迷糊。但是却是Spring的高级用户必读的一本书(还有一本pro Spring据说也不错,不过我没读过)。我过几天会写一下这本书的书评。
当然这个阶段与第四阶段是交错的,边读书边做项目学到的东西才会更多的。
六、分析源代码,扩展Spring
有人认为没有必要分析Spring的源代码,因为这是很累人又不计好的事。但是要想成为Spring的高级用户,这是必经的阶段。在学习的过程中,我们学到的不仅是Spring,更重要的是他的设计思想。不管怎样,看牛人的源代码是绝对有好处的。不过这是一个很累人的过程,要有思考准备哦!
七、等我到这个阶段的时候再谈吧,哈哈