一、Spring的理解
Spring是一个轻量级的容器,非侵入性的框架.最重要的核心概念是IOC,并提供AOP概念的实现方式,提供对持久层,事务的支持,对当前流行的一些框架(Struts,Hibernate,MVC),Sping也提供了与它们的相整合的方案. 使用Spring,我们能够减少类之间的依赖性和程序之间的耦合度,最大程度的实现松耦合,使程序更加灵活,可扩展性更强.
IOC,中文翻译为"反转控制,".DI->;"依赖注入"指的是:我们不必自己在程序代码中维护对象的依赖关系,而是通过一个xml配置文件,将类的属性和实例悄悄的注入到类里面.实现类的动态加载,使得类和类之间可以方便的切换(通过接口).
这种设计方式的思想表现为:高层模块不应该依赖低层模块,而是模块都必须依赖于抽象.程序不应改依赖于实现,而是依赖于抽象接口.应用程序不要去找容器,而是容器给我们所有想要的对象.
Spring的另一个重要的方面是支持AOP的实现: AOP的中文翻译是:面向切面编程.
面向切面编程(aop)是对面向对象编程(oop)的补充, 面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,是对应用执行过程中的步骤进行抽象,从而获得步骤之间的逻辑划分。
aop框架具有的两个特征: 1.各个步骤之间的良好隔离性2.源代码无关性
二、Spring 注解
Spring 2.5 中除了提供 @Component 注释外,还定义了几个拥有特殊语义的注释,它们分别是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,这 3 个注释和 @Component 是等效的,但是从注释类的命名上,很容易看出这 3 个注释分别和持久层、业务层和控制层(Web 层)相对应。虽然目前这 3 个注释和 @Component 相比没有什么新意,但 Spring 将在以后的版本中为它们添加特殊的功能。所以,如果 Web 应用程序采用了经典的三层分层结构的话,最好在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而用 @Component 对那些比较中立的类进行注释。
在一个稍大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。 Spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了 @Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件时一样的。
@Service用于标注业务层组件, @Controller用于标注控制层组件(如struts中的action), @Repository用于标注数据访问组件,即DAO组件, @Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
三、spring 的优点都有哪些?
ioc 解耦,提高了代码的复用性,管理对象的生命周期,不会造成对象重复创建的过程,节省了jvm的内存消耗,对事物的管理,提供了对很多其他框架的支持
四、bean的生命周期
这Spring框架中,一旦把一个bean纳入到Spring IoC容器之中,这个bean的生命周期就会交由容器进行管理,一般担当管理者角色的是BeanFactory或ApplicationContext。认识一下Bean的生命周期活动,对更好的利用它有很大的帮助。
- Bean的建立
由BeanFactory读取Bean定义文件,并生成各个实例。
- Setter注入
执行Bean的属性依赖注入。
- BeanNameAware的setBeanName()
如果Bean类实现了org.springframework.beans.factory.BeanNameAware接口,则执行其setBeanName()方法。
- BeanFactoryAware的setBeanFactory()
如果Bean类实现了org.springframework.beans.factory.BeanFactoryAware接口,则执行其setBeanFactory()方法。
- BeanPostProcessors的processBeforeInitialization()
容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processBeforeInitialization()方法。
- InitializingBean的afterPropertiesSet()
如果Bean类实现了org.springframework.beans.factory.InitializingBean接口,则执行其afterPropertiesSet()方法。
- Bean定义文件中定义init-method
在Bean定义文件中使用“init-method”属性设定方法名称,如下:
<bean id="demoBean" class="com.yangsq.bean.DemoBean" init-method="initMethod"> ....... </bean> |
这时会执行initMethod()方法,注意,这个方法是不带参数的。
- BeanPostProcessors的processAfterInitialization()
容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processAfterInitialization()方法。
- DisposableBean的destroy()
在容器关闭时,如果Bean类实现了org.springframework.beans.factory.DisposableBean接口,则执行它的destroy()方法。
- Bean定义文件中定义destroy-method
在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法
<bean id="demoBean" class="com.yangsq.bean.DemoBean" destory-method="destroyMethod"> ....... </bean> |
这时会执行destroyMethod()方法,注意,这个方法是不带参数的。
五、Spring里面如何配置数据库驱动?
使用”org.springframework.jdbc.datasource.DriverManagerDataSource”数据源来配置数据库驱动。
六、Spring里面applicationContext.xml文件能不能改成其他文件名?
ContextLoaderListener是一个ServletContextListener, 它在你的web应用启动的时候初始化。缺省情况下,它会在WEB-INF/applicationContext.xml文件找Spring的配置。你可以通过定义一个元素名字为”contextConfigLocation”来改变Spring配置文件的位置。示例如下:
org.springframework.web.context.ContextLoaderListener contextConfigLocation /WEB-INF/xyz.xml
七、AOP里面重要的几个名词概念解释
切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)来实现。
连接点(Joinpoint): 在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。 在Spring AOP中,一个连接点 总是 代表一个方法的执行。通过声明一个org.aspectj.lang.JoinPoint类型的参数可以使通知(Advice)的主体部分获得连接点信息。
通知(Advice):在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。通知的类型将在后面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。
切入点(Pointcut):匹配连接点(Joinpoint)的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。
引入(Introduction): (也被称为内部类型声明(inter-type declaration))。声明额外的方法或者某个类型的字段。 Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。
目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做被通知(advised) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied)对象。
AOP代理(AOP Proxy): AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。注意:Spring 2.0最新引入的基于模式(schema-based)风格和@AspectJ注解风格的切面声明,对于使用这些风格的用户来说,代理的创建是透明的。
织入(Weaving): 把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。 Spring和其他纯Java AOP框架一样,在运行时完成织入。
通知的类型:
前置通知(Before advice): 在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。
返回后通知(After returning advice): 在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
抛出异常后通知(After throwing advice): 在方法抛出异常退出时执行的通知。
后通知(After (finally) advice): 当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice): 包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。
环绕通知是最常用的一种通知类型。大部分基于拦截的AOP框架,例如Nanning和JBoss4,都只提供环绕通知。
切入点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP不同于其它仅仅提供拦截功能的旧技术。切入点使得定位通知(advice)可独立于OO层次。例如,一个提供声明式事务管理的around通知可以被应用到一组横跨多个对象中的方法上(例如服务层的所有业务操作)。
ioc:
2. 线程安全:struts2线程安全,springmvc线程不安全
3. 参数传递:sturts是基于类,每次发一次请求都会实例一个action,然后调用setter getter方法把request中的数据注入.一个Action对象对应一个request上下文。
spring3 mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据通过反射注入进去,一个方法对应一个request上下文。
4. 设计思想上:struts更加符合oop的编程思想, spring就比较谨慎,在servlet上扩展。
5. intercepter的实现机制:struts有以自己的interceptor机制,spring mvc用的是独立的AOP方式。这样导致struts的配置文件量还是比spring mvc大,虽然struts的配置能继承,所以我觉得论使用上来讲,spring mvc使用更加简洁,开发效率Spring MVC确实比struts2高。
spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上spring3 mvc就容易实现restful url。 struts2是类级别的拦截,一个类对应一个request上下文;实现restful url要费劲,因为struts2 action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。
spring3 mvc的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量,而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。
6. 另外,spring3 mvc的验证也是一个亮点,支持JSR303,处理ajax的请求更是方便,只需一个注解@ResponseBody ,然后直接返回响应文本即可。