Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。
Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
core
提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
spring-beans
提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。
context
建立在由 core和 beans 模块的基础上建立起来的,它以一种类似于 JNDI 注册的方式访问对象。Context 模块继承自 Bean 模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过 Servelet 容器)等功能。Context 模块也支持 Java EE 的功能,比如 EJB、JMX 和远程调用等。ApplicationContext 接口是 Context 模块的焦点。spring-context-support 提供了对第三方集成到 Spring 上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
spring-expression
提供了强大的表达式语言,用于在运行时查询和操作对象图。它是 JSP2.1 规范中定义的统一表达式语言的扩展,支持 set 和 get 属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从 Spring IoC 容器检索对象,还支持列表的投影、选择以及聚合等。
数据访问/集成
数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,它们的细节如下:(注:JDBC=Java Data Base Connectivity,ORM=Object Relational Mapping,OXM=Object XML Mapping,JMS=Java Message Service)
● JDBC 模块提供了 JDBC 抽象层,它消除了冗长的 JDBC 编码和对数据库供应商特定错误代码的解析。
● ORM 模块提供了对流行的对象关系映射 API 的集成,包括 JPA、JDO 和 Hibernate 等。通过此模块可以让这些 ORM 框架和 spring的其它功能整合,比如前面提及的事务管理。
● OXM 模块提供了对 OXM 实现的支持,比如 JAXB、Castor、XML Beans、JiBX、XStream 等。
● 事务模块为实现特殊接口类及所有的 POJO 支持编程式和声明式事务管理。(注:编程式事务需要自己写 beginTransaction()、commit()、rollback() 等事务管理方法,声明式事务是通过注解或配置由 spring 自动处理,编程式事务力度更细)
Web
Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:
● Web 模块提供面向 web 的基本功能和面向 web 的应用上下文,比如多部分(multipart)文件上传功能、使用 Servlet 监听器初始化 IoC 容器等。它还包括 HTTP 客户端以及 Spring 远程调用中与 web 相关的部分。
● Web-MVC 模块为 web 应用提供了模型视图控制(MVC)和 REST Web服务的实现。Spring 的 MVC 框架可以使领域模型代码和 web 表单完全地分离,且可以与 Spring 框架的其它所有功能进行集成。
● Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。
● Web-Portlet 模块提供了用于 Portlet 环境的 MVC 实现,并反映了 spring-webmvc 模块的功能。
IOC
为了降低耦合度,把创建对象和对象之间调用的过程交给spring。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递(注入)给它。spring主要使用DI 依赖注入。
AOP
在不修改源代码情况下增强功能,使用JDK动态代理或者CGLIB动态代理。
为了降低耦合度,把创建对象和对象之间调用的过程交给spring。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递(注入)给它。spring主要使用DI 依赖注入。
在面向对象设计的软件系统中,底层都是由N个对象相互合作实现的一个完整业务逻辑。
每个object正如一个个齿轮,它们之间紧密相连,其中只要有一个齿轮坏了,就可能会影响到整个系统,这种关系就好比每个对象之间紧密的耦合度,这种耦合度是必要的且无法避免的,但是随着工业级应用不断扩展其规模,它们之间的依赖关系越来越复杂,在后期十分不利于扩展或者修改。于是软件专家Michael Mattson提出了IOC理论,实现“解耦”,降低对象之间的耦合度。
当去除掉IOC容器后,可以看见各个对象之间没有耦合度,当需要将A做出修改时,完全不用考虑其他对象。
IOC是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象) 。然后,容器在创建bean时注入那些依赖项。此过程从根本上讲是通过使用类的直接构造或诸如服务定位器模式之类的控件来控制其依赖项的实例化或位置的bean本身的逆过程(因此称为Control的倒置)。
实现原理:工厂模式+反射
applicationcontext是beanfactory的一个子接口。
beanfactory是spring内部使用的,applicationcontext才是开发者使用的。bean在加载配置文件时并不会创建对象,而是在获取对象时才来创建,applicationcontest则是在加载文件时就创建,因为spring一般要结合使用web,在启动时就需要创建,以节省响应的时间,所以使用applicationcontext。
Bean
bean管理其实就是创建对象和注入属性,bean的xml文件在加载时就已经创建好对象了,后面直接使用getbean对应的id获取对象。
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
bean>
<bean id="..." class="...">
bean>
beans>
在创建对象时会默认使用无参构造器构造对象。
通过set方法或者构造器注入属性,set使用property标签,有产构造器使用constructor-arg标签,基本格式都是name,value。都需要通过set方法注入,默认下使用无参构造器。
还有两种通过类型和参数下标来进行的,但是都不推荐,只需要使用name这种即可。
使用ref标签,ref对应下面的bean id,这样就可以实现在userservice类中调用userdaoimpl的对象。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
beans>
@autowired可以使用在方法,属性上,不同情景下所发挥的作用也不同。
在属性上的方式,按照byType,否则就找不到。
这时会搭配qualifier,指定一个固定的bean的id。
注解支持
首先开启注解支持
可以指定扫描包中的类,添加use-default-filters=false,这样就可以自己配置filter,默认下是true,include-filter 表示要扫描的条件,expression就是指定扫描对应的注解。
使用java类来代替bean.xml
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
使用java类来代替,就需要选择注解config的context,而不再是classpath的xmlconfig。
configuration也是由component实现的,所以使用configuration也会在IOC容器中创建。
首先要明白代理模式,aop的底层就是代理模式。
AOP面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。也就是不通过修改源代码,实现功能的扩展。
AOP使用动态代理,在有接口时使用JDK代理,没有接口使用CGLIB代理。
JDK代理就是创建接口的实现类的代理对象,通过代理对象来扩展功能,也就是说代理的窗口。而CGLIB代理是通过创建子类的代理对象。
术语概念
连接点:扩展类中可以扩展的方法。
切入点:实际切入(真正扩展)的方法。
通知:实际扩展的逻辑部分,通知还以分为以下:
前置就是方法前,后就是方法后,环绕就是前后,异常是当出现异常时才显示,没有异常就没有显示,最终相当于try-catch的finally。
切面:把通知加入到切入点的过程。
一个独立的AOP框架,用来实现AOP操作,导入maven依赖
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.6version>
dependency>
编写xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="UserServiceImp">bean>
<bean id="log" class="Log">bean>
<aop:config>
<aop:pointcut id="point" expression="execution(* UserServiceImp.*(..))"/>
<aop:advisor advice-ref="log" pointcut-ref="point">aop:advisor>
aop:config>
beans>
事务是数据库操作的基本单元,是指逻辑上的一组操作。关系数据库等的事务特点:原子性,一致性,隔离性,持久性(ACID)。
spring事务管理
有两种方式:编程式事务管理和声明式事务管理。其中多使用
声明式事务管理。
n
声明式事务管理
propagation,事务传播行为:事务方法是指对数据表进行变化的操作,比如select就不属于事务方法。传播行为是指多个事务方法之间调用的过程中是如何工作的。一共有7种行为:默认下spring是required
ioslation:设置隔离级别,默认下是rpeatableread。
timeout:在限定之间内提交,否则进行回滚。
readonly:
rollback、norollback:
答:IOC是一种设计思想,在早期对象之间都是紧密相连的,高耦合,这样对应对于扩展和维护十分不便,于是就提出ioc,ioc将原本在程序创建对象的过程交给了一个中间像是一个工厂一样的,这个工厂就负责创建对象,管理对象之间的依赖关系,而当我去除掉这个工厂时呢,各个类之间由于是独立的,并不会受到影响,在spring中,通过将对象的管理交给ioc container来完成这个,只需要配置相关的文件和注释进去就可以生成出我们想要的对象。
AOP,基于动态代理,在被代理对象有实现接口时,就使用jdk动态代理,没有就是用cdlib创建子类来作为代理,这样可以不用修改原有的代码而完成功能的扩展,特别是一些每个业务块都会使用到的如日志、事务等,这样还可以提高代码复用率。
答:ioc是控制反转,它是一种思想,它的目的在于降低对象之间的耦合度,在spring中ioc 底层是靠工厂模式和反射机制实现的,这样使得对象的创建和维护交给ioc去做。
di是依赖注入,spring通过set方法或者构造器来构建对象之间的依赖关系。
答:工厂模式:通过beanfactory创建bean对象时。
代理模式:aop使用到jdk动态代理和cglib代理。
单列模式:在创建bean时,默认为单列的。
模板方法:sqlsessiontemplate。
适配器模式:aop的advice。