spring 是个Java企业级应用的开源开发框架。Spring主要用来开发Java应用,可是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发,并经过POJO为基础的编程模型促进良好的编程习惯。html
如下是Spring 框架的基本模块:前端
这是基本的Spring模块,提供spring 框架的基础功能,BeanFactory 是 任何以spring为基础的应用的核心。Spring 框架创建在此模块之上,它使Spring成为一个容器。java
Bean 工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。mysql
最经常使用的BeanFactory 实现是XmlBeanFactory 类。web
最经常使用的就是org.springframework.beans.factory.xml.XmlBeanFactory ,它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去建立一个彻底配置的系统或应用。面试
AOP模块用于发给咱们的Spring应用作面向切面的开发, 不少支持由AOP联盟提供,这样就确保了Spring和其余AOP框架的共通性。这个模块将元数据编程引入Spring。spring
经过使用JDBC抽象和DAO模块,保证数据库代码的简洁,并能避免数据库资源错误关闭致使的问题,它在各类不一样的数据库的错误信息之上,提供了一个统一的异常访问层。它还利用Spring的AOP 模块给Spring应用中的对象提供事务管理服务。sql
Spring 经过提供ORM模块,支持咱们在直接JDBC之上使用一个对象/关系映射映射(ORM)工具,Spring 支持集成主流的ORM框架,如Hiberate,JDO和 iBATIS SQL Maps。Spring的事务管理一样支持以上全部ORM框架及JDBC。数据库
Spring的WEB模块是构建在application context 模块基础之上,提供一个适合web应用的上下文。这个模块也包括支持多种面向web的任务,如透明地处理多个文件上传请求和程序级请求参数的绑定到你的业务对象。它也有对Jakarta Struts的支持。编程
Spring配置文件是个XML 文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。
Spring IOC 负责建立对象,管理对象(经过依赖注入(DI),装配对象,配置对象,而且管理这些对象的整个生命周期。
IOC 或 依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试再也不须要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
Application contexts提供一种方法处理文本消息,一个一般的作法是加载文件资源(好比镜像),它们能够向注册为监听器的bean发布事件。另外,在容器或容器内的对象上执行的那些不得不禁bean工厂以程序化方式处理的操做,能够在Application contexts中以声明的方式处理。Application contexts实现了MessageSource接口,该接口的实现以可插拔的方式提供获取本地化消息的方法。
依赖注入,是IOC的一个方面,是个一般的概念,它有多种解释。这概念是说你不用建立对象,而只须要描述它如何被建立。你不在代码里直接组装你的组件和服务,可是要在配置文件里描述哪些组件须要哪些服务,以后一个容器(IOC容器)负责把他们组装起来。
你两种依赖方式均可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。
Spring beans 是那些造成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans经过容器中配置的元数据建立。好比,以XML文件中<bean/> 的形式定义。
Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,若是它被赋为TRUE,bean 就是单件,不然就是一个 prototype bean。默认是TRUE,因此全部在Spring框架中的beans 缺省都是单件。
一个Spring Bean 的定义包含容器必知的全部配置元数据,包括如何建立一个bean,它的生命周期详情及它的依赖。
这里有三种重要的方法给Spring 容器提供配置元数据。
XML配置文件。
基于注解的配置。
基于java的配置。
当定义一个<bean> 在Spring里,咱们还能给这个bean声明一个做用域。它能够经过bean 定义中的scope属性来定义。如,当Spring要在须要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另外一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope 属性 必须设为 singleton。
Spring框架支持如下五种bean的做用域:
缺省的Spring bean 的做用域是Singleton.
不,Spring框架中的单例bean不是线程安全的。
有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。
The bean 标签有两个重要的属性(init-method和destroy-method)。用它们你能够本身定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。
当一个bean仅被用做另外一个bean的属性时,它能被声明为一个内部bean,为了定义inner bean,在Spring 的 基于XML的 配置元数据中,能够在 <property/>或 <constructor-arg/> 元素内使用<bean/> 元素,内部bean一般是匿名的,它们的Scope通常是prototype。
Spring提供如下几种集合的配置元素:
装配,或bean 装配是指在Spring 容器中把bean组装到一块儿,前提是容器须要知道bean的依赖关系,如何经过依赖注入来把它们装配到一块儿。
Spring 容器可以自动装配相互合做的bean,这意味着容器不须要<constructor-arg>和<property>配置,能经过Bean工厂自动处理bean之间的协做。
有五种自动装配的方式,能够用来指导Spring容器用自动装配方式来进行依赖注入。
自动装配的局限性是:
能够。
基于Java的配置,容许你在少许的Java注解的帮助下,进行你的大部分Spring配置而非经过XML文件。
以@Configuration 注解为例,它用来标记类能够当作一个bean的定义,被Spring IOC容器使用。另外一个例子是@Bean注解,它表示此方法将要返回一个对象,做为一个bean注册进Spring应用上下文。
相对于XML文件,注解型的配置依赖于经过字节码元数据装配组件,而非尖括号的声明。
开发者经过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml表述bean的装配关系。
注解装配在默认状况下是不开启的,为了使用注解装配,咱们必须在Spring配置文件中配置 <context:annotation-config/>元素。
这个注解代表bean的属性必须在配置的时候设置,经过一个bean定义的显式的属性值或经过自动装配,若@Required注解的bean属性未被设置,容器将抛出BeanInitializationException。
@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required同样,修饰setter方法、构造器、属性或者具备任意名称和/或多个参数的PN方法。
当有多个相同类型的bean却只有一个须要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用以消除这种混淆,指定须要装配的确切的bean。
使用SpringJDBC 框架,资源管理和错误处理的代价都会被减轻。因此开发者只需写statements 和 queries从数据存取数据,JDBC也能够在Spring框架提供的模板类的帮助下更有效地被使用,这个模板叫JdbcTemplate (例子见这里here)
JdbcTemplate 类提供了不少便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操做语句,提供自定义的数据错误处理。
Spring对数据访问对象(DAO)的支持旨在简化它和数据访问技术如JDBC,hibernate or JDO 结合使用。这使咱们能够方便切换持久层。编码时也不用担忧会捕获每种技术特有的异常。
在Spring中有两种方式访问Hibernate:
Spring支持如下ORM:
用Spring的 SessionFactory 调用 LocalSessionFactory。集成过程分三步:
Spring支持两种类型的事务管理:
大多数Spring框架的用户选择声明式事务管理,由于它对应用代码的影响最小,所以更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式容许你经过代码控制事务)少了一点灵活性。
面向切面的编程,或AOP, 是一种编程技术,容许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。
AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。好比,一个日志模块能够被称做日志的AOP切面。根据需求的不一样,一个应用程序能够有若干切面。在Spring AOP中,切面经过带有@Aspect注解的类实现。
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个咱们想实现的一个功能。
横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,好比日志,安全和数据传输,几乎应用的每一个模块都须要的功能。所以这些都属于横切关注点。
链接点表明一个应用程序的某个位置,在这个位置咱们能够插入一个AOP切面,它其实是个应用程序执行Spring AOP的位置。
通知是个在方法执行前或执行后要作的动做,其实是程序执行时要经过SpringAOP框架触发的代码段。
Spring切面能够应用五种类型的通知:
切入点是一个或一组链接点,通知将在这些位置执行。能够经过表达式或匹配的方式指明切入点。
引入容许咱们在已存在的类中增长新的方法和属性。
被一个或者多个切面所通知的对象。它一般是一个代理对象。也指被通知(advised)对象。
代理是通知目标对象后建立的对象。从客户端的角度看,代理对象和目标对象是同样的。
BeanNameAutoProxyCreator
DefaultAdvisorAutoProxyCreator
Metadata autoproxying
织入是将切面和到其余应用类型或对象链接或建立一个被通知对象的过程。
织入能够在编译时,加载时,或运行时完成。
在这种状况下,切面由常规类以及基于XML的配置实现。
在这种状况下(基于@AspectJ的实现),涉及到的切面声明的风格与带有java5标注的普通java类一致。
Spring 配备构建Web 应用的全功能MVC框架。Spring能够很便捷地和其余MVC框架集成,如Struts,Spring 的MVC框架用控制反转把业务对象和控制逻辑清晰地隔离。它也容许以声明的方式把请求参数和业务对象绑定。
Spring的MVC框架是围绕DispatcherServlet来设计的,它用来处理全部的HTTP请求和响应。
WebApplicationContext 继承了ApplicationContext 并增长了一些WEB应用必备的特有功能,它不一样于通常的ApplicationContext ,由于它能处理主题,并找到被关联的servlet。
控制器提供一个访问应用程序的行为,此行为一般经过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。Spring用一个很是抽象的方式实现了一个控制层,容许用户建立多种用途的控制器。
该注解代表该类扮演控制器的角色,Spring不须要你继承任何其余控制器基类或引用Servlet API。
该注解是用来映射一个URL到一个类或一个特定的方处理法上。
Spring帮助开发者解决了开发中基础性的问题,使得开发人员能够专一于应用程序的开发。
Spring框架自己亦是按照设计模式精心打造,这使得咱们能够在开发环境中安心的集成Spring框架,没必要担忧Spring是如何在后台进行工做的。
Spring框架至今已集成了20多个模块。这些模块主要被分以下图所示的核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。
下面列举了一些使用Spring框架带来的主要好处:
控制反转是应用于软件工程领域中的,在运行时被装配器对象来绑定耦合对象的一种编程技巧,对象之间耦合关系在编译时一般是未知的。在传统的编程方式中,业务逻辑的流程是由应用程序中的早已被设定好关联关系的对象来决定的。在使用控制反转的状况下,业务逻辑的流程是由对象关系图来决定的,该对象关系图由装配器负责实例化,这种实现方式还能够将对象之间的关联关系的定义抽象化。而绑定的过程是经过“依赖注入”实现的。
控制反转是一种以给予应用程序中目标组件更多控制为目的设计范式,并在咱们的实际工做中起到了有效的做用。
依赖注入是在编译阶段还没有知所需的功能是来自哪一个的类的状况下,将其余对象所依赖的功能对象实例化的模式。这就须要一种机制用来激活相应的组件以提供特定的功能,因此依赖注入是控制反转的基础。不然若是在组件不受框架控制的状况下,框架又怎么知道要建立哪一个组件?
在Java中依然注入有如下三种实现方式:
Spring中的 org.springframework.beans
包和 org.springframework.context
包构成了
Spring
框架
IoC
容器的基础。
BeanFactory 接口提供了一个先进的配置机制,使得任何类型的对象的配置成为可能。ApplicationContex
接口对
BeanFactory
(是一个子接口)进行了扩展,在BeanFactory的基础上添加了其余功能,好比与Spring的AOP更容易集成,也提供了处理message resource的机制(用于国际化)、事件传播以及应用层的特别配置,好比针对Web应用的WebApplicationContext。
org.springframework.beans.factory.BeanFactory
是Spring IoC容器的具体实现,用来包装和管理前面提到的各类bean。BeanFactory接口是Spring IoC 容器的核心接口。
IOC:把对象的建立、初始化、销毁交给spring来管理,而不是由开发者控制,实现控制反转。
BeanFactory 能够理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。
BeanFactory还能在实例化对象的时生成协做类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。
从表面上看,application context如同bean factory同样具备bean定义、bean关联关系的设置,根据请求分发bean的功能。但applicationcontext在此基础上还提供了其余的功能。
如下是三种较常见的 ApplicationContext 实现方式:
一、ClassPathXmlApplicationContext:从classpath的XML配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中取得。
三、XmlWebApplicationContext:由Web应用的XML文件读取上下文。
将Spring配置到应用开发中有如下三种方式:
在Spring框架中,依赖和服务须要在专门的配置文件来实现,我经常使用的XML格式的配置文件。这些配置文件的格式一般用<beans>
开头,而后一系列的
bean
定义和专门的应用配置选项组成。
SpringXML配置的主要目的时候是使全部的Spring组件均可以用xml文件的形式来进行配置。这意味着不会出现其余的Spring配置类型(好比声明的方式或基于Java Class的配置方式)
Spring的XML配置方式是使用被Spring命名空间的所支持的一系列的XML标签来实现的。Spring有如下主要的命名空间:context、beans、jdbc、tx、aop、mvc和aso。
Spring对Java配置的支持是由@Configuration注解和@Bean注解来实现的。由@Bean注解的方法将会实例化、配置和初始化一个新对象,这个对象将由Spring的IoC容器来管理。@Bean声明所起到的做用与<bean/> 元素相似。被@Configuration所注解的类则表示这个类的主要目的是做为bean定义的资源。被@Configuration声明的类能够经过在同一个类的内部调用@bean方法来设置嵌入bean的依赖关系。
最简单的@Configuration 声明类请参考下面的代码:
在上面的例子中,com.acme包首先会被扫到,而后再容器内查找被@Component 声明的类,找到后将这些类按照Sring bean定义进行注册。
若是你要在你的web应用开发中选用上述的配置的方式的话,须要用AnnotationConfigWebApplicationContext 类来读取配置文件,能够用来配置Spring的Servlet监听器ContextLoaderListener或者Spring MVC的DispatcherServlet。
Spring在2.5版本之后开始支持用注解的方式来配置依赖注入。能够用注解的方式来替代XML方式的bean描述,能够将bean描述转移到组件类的内部,只须要在相关类上、方法上或者字段声明上使用注解便可。注解注入将会被容器在XML注入以前被处理,因此后者会覆盖掉前者对于同一个属性的处理结果。
注解装配在Spring中是默认关闭的。因此须要在Spring文件中配置一下才能使用基于注解的装配模式。若是你想要在你的应用程序中使用关于注解的方法的话,请参考以下的配置。
在 <context:annotation-config/>标签配置完成之后,就能够用注解的方式在Spring中向属性、方法和构造方法中自动装配变量。
下面是几种比较重要的注解类型:
Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,须要执行一系列的初始化操做以达到可用的状态。一样的,当一个bean不在被调用时须要进行相关的析构操做,并从bean容器中移除。
Spring bean factory 负责管理在spring容器中被建立的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。
Spring框架提供了如下四种方式来管理bean的生命周期事件:
使用customInit()
和 customDestroy()
方法管理
bean
生命周期的代码样例以下:
Spring容器中的bean能够分为5个范围。全部范围的名称都是自说明的,可是为了不混淆,仍是让咱们来解释一下:
全局做用域与Servlet中的session做用域效果相同。
在Spring框架中,不管什么时候bean被使用时,当仅被调用了一个属性。一个明智的作法是将这个bean声明为内部bean。内部bean能够用setter注入“属性”和构造方法注入“构造参数”的方式来实现。
好比,在咱们的应用程序中,一个Customer类引用了一个Person类,咱们的要作的是建立一个Person的实例,而后在Customer内部使用。
Spring提供了如下四种集合类的配置元素:
下面看一下具体的例子:
第一种方法是使用以下面代码所示的<props> 标签:
在Spring框架中,在配置文件中设定bean的依赖关系是一个很好的机制,Spring容器还能够自动装配合做关系bean之间的关联关系。这意味着Spring能够经过向Bean Factory中注入的方式自动搞定bean之间的依赖关系。自动装配能够设置在每一个bean上,也能够设定在特定的bean上。
@Autowired
注解来自动装配指定的
bean
。在使用
@Autowired
注解以前须要在按照以下的配置方式在
Spring
配置文件进行配置才可使用。
AutowiredAnnotationBeanPostProcessor
达到相同的效果。@Autowired
来标注了。
在Spring框架中共有5种自动装配,让咱们逐一分析。
要使用 @Autowired
,须要注册
AutowiredAnnotationBeanPostProcessor
,能够有如下两种方式来实现:
一、引入配置文件中的<bean>下引入 <context:annotation-config>
AutowiredAnnotationBeanPostProcessor
在产品级别的应用中,IoC容器可能声明了数十万了bean,bean与bean之间有着复杂的依赖关系。设值注解方法的短板之一就是验证全部的属性是否被注解是一项十分困难的操做。能够经过在<bean>中设置“dependency-check”来解决这个问题。
在应用程序的生命周期中,你可能不大愿意花时间在验证全部bean的属性是否按照上下文文件正确配置。或者你宁肯验证某个bean的特定属性是否被正确的设置。即便是用“dependency-check”属性也不能很好的解决这个问题,在这种状况下,你须要使用@Required
注解。
须要用以下的方式使用来标明bean的设值方法。
RequiredAnnotationBeanPostProcessor
是Spring中的后置处理用来验证被@Required
注解的bean属性是否被正确的设置了。在使用RequiredAnnotationBeanPostProcesso
来验证bean
属性以前,首先要在IoC
容器中对其进行注册:@Required
注解过的话,后置处理器会抛出一个BeanInitializationException
异常。
@Autowired注解对自动装配什么时候何处被实现提供了更多细粒度的控制。@Autowired
注解能够像
@Required
注解、构造器同样被用于在
bean
的设值方法上自动装配
bean
的属性,一个参数或者带有任意名称或带有多个参数的方法。
好比,能够在设值方法上使用@Autowired
注解来替代配置文件中的
<property>
元素。当
Spring
容器在
setter
方法上找到
@Autowired
注解时,会尝试用
byType 自动装配。
固然咱们也能够在构造方法上使用@Autowired
注解。带有@Autowired
注解的构造方法意味着在建立一个bean时将会被自动装配,即使在配置文件中使用<constructor-arg>
元素。
@Qualifier
注解意味着能够在被标注
bean
的字段上能够自动装配。
Qualifier注解能够用来取消Spring不能取消的bean应用。
下面的示例将会在Customer的person属性中自动装配person的值。
Spring
会知道要自动装配哪一个person bean么?不会的,可是运行上面的示例时,
会抛出下面的异常:
@Quanlifier
注解来告诉Spring容器要装配哪一个bean:请注意如下明显的区别:
ObjectCurrentlyInCreationException异常,由于在B对象被建立以前A对象是不能被建立的,反之亦然。因此Spring用设值注入的方法解决了循环依赖的问题,因对象的设值方法是在对象被建立以前被调用的。
Spring的ApplicationContext
提供了支持事件和代码中监听器的功能。
咱们能够建立bean用来监听在ApplicationContext
中发布的事件。ApplicationEven
t类和在ApplicationContext
接口
中处理的事件,若是一个bean实现了ApplicationListener
接口,当一个ApplicationEvent
被发布之后,bean会自动被通知。
Spring 提供了如下5中标准的事件:
除了上面介绍的事件之外,还能够经过扩展ApplicationEvent
类来开发自定义的事件。
publishEvent()方法来发布自定义事件。
在FileSystemResource
中须要给出spring-config.xml
文件在你项目中的相对路径或者绝对路径。在ClassPathResource
中spring会在ClassPath中自动搜寻配置文件,因此要把ClassPathResource
文件放在ClassPath下。
若是将spring-config.xml
保存在了src文件夹下的话,只需给出配置文件的名称便可,由于src文件夹是默认。
简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。
Spring框架中使用到了大量的设计模式,下面列举了比较有表明性的:
JmsTemplate
, JpaTemplate。
DispatcherServlet
来对请求进行分发。
BeanFactory
/ ApplicationContext
接口的核心理念。
IoC Inverse of Control 反转控制的概念,就是将本来在程序中手动建立UserService对象的控制权,交由Spring框架管理,简单说,就是建立UserService对象控制权被反转到了Spring框架
DI:Dependency Injection 依赖注入,在Spring框架负责建立Bean对象时,动态的将依赖对象注入到Bean组件
面试题: IoC 和 DI的区别?
IoC 控制反转,指将对象的建立权,反转到Spring容器 , DI 依赖注入,指Spring建立对象的过程当中,将对象依赖属性经过配置进行注入
开发中基本都在使用ApplicationContext, web项目使用WebApplicationContext ,不多用到BeanFactory
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
IHelloService helloService = (IHelloService) beanFactory.getBean("helloService");
helloService.sayHello();
1)使用类构造器实例化(默认无参数)
<bean id="bean1" class="cn.itcast.spring.b_instance.Bean1"></bean>
//下面这段配置的含义:调用Bean2Factory的getBean2方法获得bean2
<bean id="bean2" class="cn.itcast.spring.b_instance.Bean2Factory" factory-method="getBean2"></bean>
<bean id="bean3Factory" class="cn.itcast.spring.b_instance.Bean3Factory"></bean>
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
1)在配置 <bean> 元素,经过 init-method 指定Bean的初始化方法,经过 destroy-method 指定Bean销毁方法
<beanid="lifeCycleBean"class="cn.itcast.spring.d_lifecycle.LifeCycleBean"init-method="setup"destroy-method="teardown"></bean>
* destroy-method 只对 scope="singleton" 有效
* 销毁方法,必须关闭ApplicationContext对象(手动调用),才会被调用
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.close();
2)Bean的完整生命周期 (十一步骤)【了解内容,可是对于spring内部操做理解有必定帮助】
①instantiate bean对象实例化
②populate properties 封装属性
③若是Bean实现BeanNameAware 执行 setBeanName
④若是Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
⑤若是存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization,BeanPostProcessor接口提供钩子函数,用来动态扩展修改Bean。(程序自动调用后处理Bean)
publicclassMyBeanPostProcessorimplementsBeanPostProcessor{
publicObject postProcessAfterInitialization(Object bean,String beanName)
throwsBeansException{
System.out.println("第八步:后处理Bean,after初始化。");
//后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
return bean;//返回bean,表示没有修改,若是使用动态代理,返回代理对象,那么就修改了。
}
publicObject postProcessBeforeInitialization(Object bean,String beanName)
throwsBeansException{
System.out.println("第五步:后处理Bean的:before初始化!!");
//后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
return bean;//返回bean自己,表示没有修改。
}
}
⑦调用<bean init-method="init"> 指定初始化方法 init
⑧若是存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
⑨执行业务处理
⑩若是Bean实现 DisposableBean 执行 destroy
⑪调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
(1)bean定义
在配置文件里面用<bean></bean>来进行定义。
(2)bean初始化
有两种方式初始化:
A.在配置文件中经过指定init-method属性来完成
B.实现org.springframwork.beans.factory.InitializingBean接口
(3)bean调用
有三种方式能够获得bean实例,并进行调用
(4)bean销毁
销毁有两种方式
A.使用配置文件指定的destroy-method属性
B.实现org.springframwork.bean.factory.DisposeableBean接口
##做用域
singleton
当一个bean的做用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,而且全部对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
prototype
Prototype做用域的bean会致使在每次对该bean请求(将其注入到另外一个bean中,或者以程序的方式调用容器的getBean() 方法)时都会建立一个新的bean实例。根据经验,对全部有状态的bean应该使用prototype做用域,而对无状态的bean则应该使用 singleton做用域
request
在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义建立而成。该做用 域仅在基于web的Spring ApplicationContext情形下有效。
session
在一个HTTP Session中,一个bean定义对应一个实例。该做用域仅在基于web的Spring ApplicationContext情形下有效。
global session
在一个全局的HTTP Session中,一个bean定义对应一个实例。典型状况下,仅在使用portlet context的时候有效。该做用域仅在基于 web的Spring ApplicationContext情形下有效。
面向切面编程(AOP)提供另一种角度来思考程序结构,经过这种方式弥补了面向对象编程(OOP)的不足,除了类(classes)之外,AOP提供了切面。切面对关注点进行模块化,例如横切多个类型和对象的事务管理
Spring的一个关键的组件就是AOP框架,能够自由选择是否使用AOP 提供声明式企业服务,特别是为了替代EJB声明式服务。最重要的服务是声明性事务管理,这个服务创建在Spring的抽象事物管理之上。容许用户实现自定义切面,用AOP来完善OOP的使用,能够把Spring AOP看做是对Spring的一种加强
BeanFactory:产生一个新的实例,能够实现单例模式
BeanWrapper:提供统一的get及set方法
ApplicationContext:提供框架的实现,包括BeanFactory的全部功能
<bean id=”dataSource”>
<property name=”driverClassName”>
<property name=”url”>
<value>jdbc:hsqldb:db/appfuse</value>
</property>
<property name=”username”><value>abc</value></property>
<property name=”password”><value>abc</value></property>
</bean>
ContextLoaderListener是一个ServletContextListener, 它在你的web应用启动的时候初始化。缺省状况下, 它会在WEB-INF/applicationContext.xml文件找Spring的配置。 你能够经过定义一个<context-param>元素名字为”contextConfigLocation”来改变Spring配置文件的 位置。示例以下:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/xyz.xml</param-value>
</context-param>
</listener-class>
</listener>
添加hibernate mapping 文件到web/WEB-INF目录下的applicationContext.xml文件里面。示例以下:
<property name=”mappingResources”>
<list>
<value>org/appfuse/model/User.hbm.xml</value>
</list>
</property>
Spring使用ThreadLocal解决线程安全问题
咱们知道在通常状况下,只有无状态的Bean才能够在多线程环境下共享,在Spring中,绝大部分Bean均可以声明为singleton做用域。就是由于Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,由于有状态的Bean就能够在多线程中共享了。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
在同步机制中,经过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析何时对变量进行读写,何时须要锁定某个对象,何时释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
而ThreadLocal则从另外一个角度来解决多线程的并发访问。ThreadLocal会为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。由于每个线程都拥有本身的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,能够把不安全的变量封装进ThreadLocal。
因为ThreadLocal中能够持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,须要强制类型转换。但JDK5.0经过泛型很好的解决了这个问题,在必定程度地简化ThreadLocal的使用。
归纳起来讲,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不一样的线程排队访问,然后者为每个线程都提供了一份变量,所以能够同时访问而互不影响。
事务就是对一系列的数据库操做(好比插入多条数据)进行统一的提交或回滚操做,若是插入成功,那么一块儿成功,若是中间有一条出现异常,那么回滚以前的全部操做。这样能够防止出现脏数据,防止数据库数据出现问题。
开发中为了不这种状况通常都会进行事务管理。Spring中也有本身的事务管理机制,通常是使用TransactionMananger进行管 理,能够经过Spring的注入来完成此功能。spring提供了几个关于事务处理的类:
TransactionDefinition //事务属性定义
TranscationStatus //表明了当前的事务,能够提交,回滚。
PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类 AbstractPlatformTransactionManager,咱们使用的事务管理类例如 DataSourceTransactionManager等都是这个类的子类。
通常事务定义步骤:
TransactionDefinition td =newTransactionDefinition();
TransactionStatus ts = transactionManager.getTransaction(td);
try
{ transactionManager.commit(ts);
}
catch(Exception e){
编程式主要使用transactionTemplate。省略了部分的提交,回滚,一系列的事务对象定义,需注入事务管理对象.
void add(){
transactionTemplate.execute(newTransactionCallback(){
}
}
使用TransactionProxyFactoryBean:PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED,readOnly
围绕Poxy的动态代理 可以自动的提交和回滚事务
org.springframework.transaction.interceptor.TransactionProxyFactoryBean
PROPAGATION_REQUIRED–支持当前事务,若是当前没有事务,就新建一个事务。这是最多见的选择。
PROPAGATION_SUPPORTS–支持当前事务,若是当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY–支持当前事务,若是当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW–新建事务,若是当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED–以非事务方式执行操做,若是当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER–以非事务方式执行,若是当前存在事务,则抛出异常。
PROPAGATION_NESTED–若是当前存在事务,则在嵌套事务内执行。若是当前没有事务,则进行与 PROPAGATION_REQUIRED相似的操做。
切面(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框架同样,在运行时完成织入。