Spring是一个开源框架,为简化企业级应用开发而生。Spring可以使简单的JavaBean实现以前只有EJB才能实现的功能。Spring是一个IOC和AOP容器框架。
Spring容器的主要核心是:
控制反转(IOC):传统的java开发模式中,当需要一个对象时,我们会自己使用new或者getInstance等直接或间接调用构造方法创建一个对象。而在spring开发模式中,spring容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用spring提供的对象就可以了,这就是控制反转的思想。
依赖注入(DI):spring使用javaBean对象的set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,这就是依赖注入的思想。
面向切面编程(AOP):在面向对象编程(oop)思想中,我们将事务纵向抽成一个个对象。而在面向切面编程中,我们将一个个对象某些类似的方法横向抽成一个切面,对这个切面进行一些如权限控制、事务管理、记录日志等公用操作处理的过程就是面向切面编程的思想。AOP底层是动态代理,如果接口采用JDK动态代理,如果是类采用CGLIB方式实现动态代理。
1、代理模式--spring中两种代理方式,若目标对象实现了若干接口,spring使用jdk的java.lang.reflect.Proxy类代理。若目标兑现没有实现任何接口,spring使用CGLIB库生成目标类的子类。
2、单例模式--在spring的配置文件中设置bean默认为单例模式
3、模板方法模式--用来解决代码重复的问题。比如:RestTemplate、JmsTemplate、JpaTemplate。
4、工厂模式--在工厂模式中,我们在创建对象是不会对客户端暴露创建逻辑,并且是通过使用同一个接口来指向新创建的对象。spring中使用beanFactory来创建对象的实例。
spring在2.5版本以后开始支持注解的方式来配置依赖注入。可以用注解的方式来代替xml中的bean描述。注解注入将会被容器在xml注入之前被处理,所以后者会覆盖掉对于同一个属性的处理结果。
注解装配在spring中默认是关闭的。所以需要在spring的核心配置文件中配置一下才能使用基于注解的装配模式。配置方式如下:
常用的注解:
@Require:该注解应用于设置方法
@Autowire:该注解应用于有值设值方法、非设值方法、构造方法和变量
@Qualifier:该注解和@Autowired搭配使用,用于消除特定bean自动装配的歧义
bean定义:在配置文件里面用
bean初始化:有两种方式初始化
在配置文件中通过指定init-method属性来完成
实现org.springframework.beans.factory.InitializingBean接口
bean调用:有三种方式可以得到bean实例,并进行调用
bean销毁:销毁有两种方式
使用配置文件指定的destroy-method属性
实现org.springframework.bean.factory.DisposeableBean接口
1、核心容器:包括core、beans、context、EL模块
Core模块:封装了框架依赖的最底层部分,包括资源访问、类型转换及一些常用工具类。
Beans模块:提供了框架的基础部分,包括翻转控制和依赖注入。其中Bean Factory是容器核心,本质是工厂设计模式的实现,而且无需编程实现单例设计模式,单例完全由容器控制,而且提倡面向接口编程,而非面向实现编程,所有应用程序对象及对象间关系由框架管理,从而真正把你从程序逻辑中吧维护对象之间的依赖关系提取出来,所有这些依赖关系都由BeanFactory来维护。
Context模块:以core和beans为基础,继承beans模块功能并添加资源绑定、数据验证、国际化、javaEE支持、容器生命周期、事件传播等;核心接口是ApplicationContext
EL模块:提供强大的表达式语言支持,支持访问和修改属性值,方法调用,支持访问及修改数组、容器和索引器、命名变量、支持算数和逻辑运算、支持从Spring容器获取Bean,它也支持列表投影、选择和一般的列表聚合等。
2、AOP、Aspects模块:
AOP模块:Spring AOP模块提供了符合AOPAlliance规范的面向切面的编程实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中,这样各专其职,降低业务逻辑和通用功能的耦合。
Aspects模块:提供了对AspectJ的继承,AspectJ提供了比Spring ASP更强大的功能。
数据访问/集成模块:该模块包括了JDBC、ORM、OXM、JMS和事务管理。
事务模块:该模块用于Spring管理事务,只要是Spring管理对象都能得到Spring管理事务的好处,无需在代码中进行事务控制了,而且支持编程和生命性的事务管理。
JDBC模块:提供了一个JDBC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。
ORM模块:提供与流行的“对象--关系”映射框架的无缝集成,包括Hibernate、JPA、MyBatis等。而且可以使用Spring事务管理,无需额外控制事务。
OXM模块:提供了一个队Object/XML映射实现,将java对象映射成XML数据,或者将XML数据映射成java对象,Object/XML映射实现包括JAXB、Castor、XMLBeans和XStream。
JMS模块:用于JMS(Java Messaging Service),提供一套“消息生产者,消息消费者”模板用于更加简单的使用JMS,JMS用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
Web/Remoting模块:Web/Remoting模块包含了Web、Web-Servlet、Web-Struts、Web-Porlet模块。
Web模块:提供了基础的web功能。例如多文件上传、集成IoC容器、远程过程访问(RMI、Hessian、Burlap)以及Web Service支持,并提供一个RestTemplate类来提供方便的Restful services访问。
Web-Servlet模块:提供了一个Spring MVC Web框架实现。Spring MVC框架提供了基于注解的请求资源注入,更简单的数据绑定、数据验证等及一套非常易用的JSP标签,完全无缝与Spring其他技术协作。
Web-Struts模块:提供了与Struts无缝集成,Struts1.x和Struts2.x都支持
Test模块:Spring支持Junit和TestNG测试框架,而且还额外提供了一些基于Spring的测试功能,比如在测试Web框架时,模拟Http请求的功能
Spring能帮我们根据配置文件创建及组装对象之间的依赖关系。Spring根据配置文件来进行创建及组装对象之间的依赖关系,只需要改配置文件即可。
Spring面向切面编程能帮助我们无耦合的实现日志记录、性能统计、安全控制。Spring面向切面编程能提供一种更好的方式来完成,一般通过配置方式,而且不需要在现有代码中添加任何额外代码,现有代码专注业务逻辑。
Spring能非常简单的帮我们管理数据库事务。采用Spring,我们只需获取连接,执行SQL,其他事物相关的都交给Spring来管理了。
Spring还能与第三方数据库访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板,来方便数据库访问。
Spring还能与第三方Web(如Struts、JSF)框架无缝集成,而且自己也停了一套SpringMVC框架,来方便web层搭建。
Spring能方便与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)
声明式事务管理的定义:用在Spring配置文件中声明式的处理事务来代替代码是的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要改变事务管理策划的话,也只需要爱定义文件中重新配置即可,这样维护起来极其方便。
基于TransactionInterceptor的声明式事务管理:两个次要的属性:transactionManager,用来指定一个事务治理器,并将具体事务相关的操作请托给他,其他一个是Properties类型的transactionAttributes属性,概述性的每一个键值对中,键指定的是方法名,方法名可以行使通配符,而值就是表现呼应方法的所运用的事务属性。
基于TransactionProxyFactoryBean的声明事务管理,设置配置文件与先前比照简化了许多。我们把这类设置配置文件称为Spring经典的声明式事务治理。
基于
基于@Transactional的声明式事务管理:Spring 2.x还引入了基于Annotation的体式格式,具体次要初级@Transactional标注。@Transactional可以浸染于接口、接口方法、类和类方法上。算作用于类上时,该类的一切public方法将都是具有该类型的事务属性。
编程式事务管理的定义:在代码中西安市调用beginTransaction()、commit()、rollback()等事务治理相关的方法,这就是编程式事务管理。Spring对事物的编程式管理有基于底层的API的编程式管理和基于TransactionTemplate的编程式事务管理两种方式。
基于底层API的编程式管理:凭借PlatformTransactionManager、TransactionDefinition和TransactionStatus三个焦点接口,来实现编程式事务管理。
基于TransactionTemplate的编程式事务管理,为了不损坏代码原有的提哦啊领,避免出现每一个方法中都包括相同的启动事务、提交、回滚事务样板代码的现象,spring调给你来个transactionTemplate模板来是想编程式事务管理。
编程式事务与声明式事务的区别:
编程式事务是自己写事务处理的类,让后调用
声明式事务实在配置文件中配置,一般搭配在框架里面使用
Bean工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从真正的应用代码中分离。常用的BeanFactory实现有DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等。
Spring-DAO并非Spring的一个模块,它实际上是指示你写DAO操作、写好DAO操作的一些规范。因此,对于访问你的数据它既没有提供接口也没有提供实现更没有提供模板。在写一个DAO的时候,你应该使用@Repository对其进行注解,这样底层技术(JDBC、Hibernate、JPA等)相关异常才能一致性的翻译为相应的DataAccessExceprion子类。
Spring-JDBC提供了JDBC模板类,它一触类连接代码以帮你专注于SQL查询和相关参数。Spring-JDBC还提供了一个JDBCDAOSupport,这样你可以对你的DAO进行扩展开发。它主要定义了两个属性:一个DataSource和一个jdbcTemplate,它们都可以用来实现DAO方法,jdbcDaoSupport还提供了一个将SQL异常转换为SpringDataAccessException的异常翻译器。
Spring-ORM是一个囊括了很多持久层技术(JPA、JDO、Hibernate、iBatis)的总括模块。对于这些技术中的每一个,Spring都提供了集成类,这样每一种技术都能够在遵循Spring的配置原则下进行使用,并平稳的和Spring事务管理进行集成。
对于每一种技术,配置主要在于讲一个DataSource bean注入到某种SessionFactory或者EntityManagerFactory等bean中。纯JDBC不需要这样一个集成类(JdbcTemplate除外),因为JDBC仅依赖于一个DataSource。
如果你计划使用一种ORM技术,比如JPA或者Hibernate,那么你就不需要Spring-JDBC模块了,你需要的是这个Spring-ORM模块。
Spring的WEB模块是构建在application context模块基础之上,提供一个适合web应用的上下文。这个模块也包括支持多种面向web的任务,如透明的处理多个文件上传请求和程序级请求参数的绑定到你的业务对象。他也有对Jakara Struts的支持。
十一、Spring配置文件有什么作用?
Spring配置文件使各XML文件,这个文件包含了类型西,描述了如何配置他们,以及如何相互调用。
IOC控制反转:Spring IOC负责创建对象,管理对象。通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
IOC或依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和JNDI查找机制。最小的代价和最小的侵入性使松散耦合得以实现。IOC容器支持加载服务时的饿汉式初始化和懒加载。
FileSystemXMLApplication:此容器从一个XML文件中加载beans的定义,XML Bean配置文件的全路径名必须提供给它的构造函数。
ClassPathXmlApplication:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath,因为这个容器classpath里找bean配置。
WebXmlApplication:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean
1、BeanFactory
基础类型的IOC容器,提供完整的IOC服务支持,如果没有特殊指定,默认采用延迟初始化策略。相对来说,容器启动初期速度较快,所需资源有限。
2、ApplicationContext
ApplicationContext实在BeanFactory基础上构建,是相对于比较高级的容器实现,除了BeanFactory的所有支持外,Application还提用了事件发布,国际化支持的功能。ApplicationContext管理的对象,在容器启动后默认全部初始化并且绑定完成。
平常的java开发中,程序员在某个类中需要依赖其他类的方法,则通常new一个以来累在调用类实例的方法,这种开发在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不有程序员实例化,而是通过spring容器帮我们new指定实例并且将实力注入到需要该对象的类中。依赖注入的另一种说法是“控制反转”,通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员的,而控制反转是指new实例工作不由我们来做而是交给spring容器来做。
Spring提供了多种依赖注入的方式
set注入
构造器注入
静态工厂的方式注入
实例工厂的方法注入
Spring beans是哪些形成Spring应用的主干的ava对象。他们被Spring IOC容器初始化,装配和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中
Spring框架定义的beans都是单例beans。
一个Spring bean的定义包含容器必须的所有配置元数据,包括如何创建一个bean,它的生命周期详情及它的依赖。
当定义一个
Spring框架支持一下五中Bean的作用域:
singleton:bean在每个Spring ioc容器中只有一个实例。
prototype:一个bean的定义可以有多个实例。
request:每次http请求都会创建一个bean,该作用域尽在基于web到的spring ApplicationContext情形下有效。
session:在一个HttpSession中,一个bean的定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
缺省的Spring bean的作用域是Singleton。
Spring框架中单例bean不是线程安全的
当一个bean仅被用作另一个bean的属性时,他能被声明为一个内部bean,为了定义inner bean,在Spring的基于XML的配置元数据中,可以在
Spring提供一下几种集合的配置元素:
类型用于注入一列值,允许有相同的值。
无需在Spring配置文件中描述javaBean之间的依赖关系(如配置
有5中自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
no:默认的方式是不进行自动装配,通过显示设置ref属性来进行装配。
byName:通过参数名自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和bena的属性具有相同名字的bean。
byType:通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
construct:这个方式类似于byType,但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
autodetect:首先尝试constructor来自动装配,如果无法工作,则使用byType方式。
基于java的配置,允许你在少量的java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。以@Configuration注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
相对于XML文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用xml标书bean的装配关系。
注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置
使用Spring JDBC框架,资源管理和错误处理的代价都会被减轻。所以开发者只需要写statements和queries从数据中存取数据,JDBC也可以在Spring框架提供的模板类的帮助下更有效地被使用,这个模板叫jdbcTemplate。jdbcTemplate类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。
在Spring中有两种方式访问Hibernate
控制反转HibernateTemplate和Callback
集成HibernateDAOSupport一共一个AOP拦截器。
Hibernate、iBatis、JPA、TopLink、JDO、OJB
AOP即面向切面编程,可以说是OOP(面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码旺旺横向的散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和同名的持续性也如此,这种散布在各处的无关代码被称为横切,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
AOP技术恰恰相反,它利用一种称为横切的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为Aspect,即切面。所谓切面,简单说就是那些与业务无关,却为业务模块锁公共调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
使用横切技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程时核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多出,而各处基本相似,比如权限认证、日志、事务。AOP的作用在于分离系统中的各个关注点,将核心关注点的横切关注点分离开。
AOP的核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同,一个应用程序可以有若干切面。在Spring AOP中,切面通过带有@Aspect注解的类实现。
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都数据横切关注点。
被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器。
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过Spring AOP框架触发的代码段。
Spring切面可以应用5中类型的通知:
before:前置通知,在一个方法执行前被调用;
after:在方法执行后调用的通知,无论方法执行是否成功。
after-returning:仅当方法陈宫完成后执行的通知。
after-throwing:在方法抛出异常退出时执行的通知。
around:在方法执行之前和之后调用的通知。
切入点是一个或一组连接点,通知健在这些位置执行。可以通过表达式或匹配的方式指明切入点。
被一个或多个切面所通知的对象。它通常是一个代理对象。也指被通知对象。
代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标是一样的。
织入是将切面和到其他应用类型或对象连接或创建一个被通知对象的过程。织入可以在编译时,加载时,或运行时完成。