Spring
2021-03-29 10:37:52 1 举报
AI智能生成
本流程图主要内容来自陈雄华,林开雄,文建国编著的《精通Spring4.x 企业应用开发实战》,此书使本人受益匪浅,书中有各种实例,作者也将每一章的代码托管到了百度网盘,链接在书的前言里。本流程图的建造是为了当有知识遗忘时快速拾取,流程图本生也是理清思路极好的方法; 流程图尚不完整本人也是会随着学习不断的更新整合。
作者其他创作
大纲/内容
简介
Spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版。Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率。
Spring理念
使现有技术更加实用,本身可以认为是一个大杂烩 ,就是整合了现有的框架技术
Spring Framework
Core
IoC Container
简介
某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定,即由Spring容器借由Bean配置来进行控制。
因为IoC确实不够开门见山,因此业界曾进行了广泛的讨论,最终软件界的泰斗级人物Martin Fowler提出了DI (Dependency Injection,依赖注入)的概念用来代替IoC,即让调用类对某一接口实现类的依赖关系由第三方(容器或协作类)注入,以移除调用类对某一接口实现类的依赖。“依赖注入”这个名词显然比“控制反转”直接明了、易于理解。
Bean
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是由Spring IoC容器实例化、组装和管理的对象。也就是说,
bean只是应用程序中众多对象中的一个(不是Bean的对象为POJO)。bean及其之间的依赖关系反映在容器使用的配置元数据中。
bean只是应用程序中众多对象中的一个(不是Bean的对象为POJO)。bean及其之间的依赖关系反映在容器使用的配置元数据中。
Bean的生命周期
Bean之间的关系
Bean的作用域
底层实现
Spring为什么会有这种“神奇”的力量,仅凭一个简单的配置文件,就能魔法般地实例化并装配好程序所用的Bean呢?这种“神奇”的力量归功于Java语言本身的类反反射机制。
org.springframework.beans
BeanFactory接口
提供了能够管理任何类型对象的高级配置机制
org.springframework.context
ApplicationContext接口
继承了BeanFactory接口
BeanFactory -> ListableBeanFactory -> ApplicationContext
在BeanFactory增加的内容
更容易与Spring的AOP特性集成
消息资源处理(用于i18n及国际化)
事件发布(Event publication)
特定于应用程序层的上下文,比如web应用程序中使用的WebApplicationContext
表示Spring IoC容器,通过元数据负责实例化、配置和组装bean
元数据
metadata ,存在XML,注解或Java代码中,虽然XML一直是定义配置元数据的传统格式,但可以通过提供少量XML配置以声明方式启用对其他方法的支持,从而指示容器使用Java注释或代码作为元数据格式
配置原数据
通过XML
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- collaborators and configuration for this bean go here -->
</bean>
The id attribute is a string that identifies the individual bean definition.
The class attribute defines the type of the bean and uses the fully qualified
classname.
The class attribute defines the type of the bean and uses the fully qualified
classname.
业务层对象(service layer objects)配置文件
数据访问层对象(data access objects)配置文件
表示层对象(presentation objects)配置文件
infrastructure objects配置文件
Java Persistence API 配置文件
通过注解
通过Java代码
Spring提供的ApplicationContext接口实现类
ClassPathXmlApplicationContext
下面的例子将外部文件services.xml和daos.xml的元数据在容器加载了
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
FileSystemXmlApplicationContext
在IoC容器中装配Bean
依赖注入
基于XML的配置
定义Bean
属性注入
通过setter(set方法)注入Bean的属性值或依赖对象,属性注入指通过setXxx()方法注入Bean的属性值或依赖对象。由于属性注入方式
具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。
具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。
属性注入要求Bean提供一个默认的构造方法(无参构造),并为需要注入的属性提供对应的Setter方法。Spring 先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。
<bean id="..." class="..." >
<property name="xxx" value="" />
<property name="xxx" ref="" />①
</bean>
<property name="xxx" value="" />
<property name="xxx" ref="" />①
</bean>
①中的ref指引入另一个bean,如这个bean的成员变量中有一个引用类型则用ref
上别的name,xxx对应这setXxx,这里必需按编程规约来命名,类的成员变量前两个字母只能都大写,要不都小写(JavaBean规范)
在属性注入时,Spring 按JavaBean规范找到配置属性所对应的Setter方法,并使用Java反射机制调用Setter方法完成属性注入。但Java反射机制并不会记住构造函数的入参名,因此我们无法通过指定构造函数的入参名进行构造函数注入的配置,只能通过入参类型和索引信息间接确定构造函数配置项和入参的对应关系。这也就是为什么没传name而传的是type或下别的index
构造函数注入
构造函数注入是除属性注入外的另一种常用的注入方式,它保证一些必要的属性在Bean实例化时就得到设置,确保Bean在实例化后就可以使用。
使用构造函数注入的前提是Bean必须提供带参的构造方法。
按类型匹配入参
<bean id="" class="">
<constructor-arg type="java.lang.String" value="红旗CA72"></constructor-arg>①
<constructor-arg type="java.lang.Double" value="20000"></constructor-arg>②
</bean>
<constructor-arg type="java.lang.String" value="红旗CA72"></constructor-arg>①
<constructor-arg type="java.lang.Double" value="20000"></constructor-arg>②
</bean>
Spring 的配置文件采用和元素标签顺序无关的策略,这种策略可以在一定程度上保证配置信息的确定性,避免一些似是而非的问题。因此,①和②处的<constructor-arg> 位置并不会对最终的配置效果产生影响。
按索引匹配入参
在按类型匹配入参的方式中Spring仅通过type属性指定的参数类型就可以知道“红旗CA72”对应String类型入参,而“20000”对应double类型的入参。但是如果构造函数有两个类型相同的入参,那么仅通过type就无法确定对应关系了,这时需要通过入按索引匹配的方式进行确定。
<constructor-arg index="0" value="红旗CA72"></constructor-arg>
联合使用类型和索引匹配入参
当有两个构造器的传参数量相同,且又有相同的类型时使用联合的方式例:
foo(Integer a, Integer b, String c){}
foo(Integer a, Integer b ,Boolean c){}
foo(Integer a, Integer b, String c){}
foo(Integer a, Integer b ,Boolean c){}
<constructor-arg index="" value="" type=""></constructor-arg>
对于因参数数目相同而类型不同引起的潜在配置歧义问题,Spring容器可以正确启动且不会给出报错信息,它将随机采用一个匹配的构造函数实例化Bean,而被选择的构造函数可能并不是用户所期望的那个。因此,必须特别谨慎,以避免潜在的错误。
通过自身类型反射匹配入参
如果Bean构造函数入参的类型是可辨别的(非基础数据类型且入参类型各异),由于Java反射机制可以获取构造函数入参的类型,即使构造函数注入的配置不提供类型和索引的信息,Spring依旧可以正确地完成构造函数的注入工作。
但是为了避免潜在配置歧义引起的张冠李戴的情况,如果Bean存在多个构造函数,那么使用显式指定index和type属性不失为一种良好的配置习惯。
循环依赖问题
Spring容器能对构造函数配置的Bean进行实例化有一个前提,即Bean构造函数入参引用的对象必须已经准备就绪。由于这个机制的限制,如果两个Bean都采用构造函数注入,而且都通过构造函数入参引用对方,就会发生类似于线程死锁的循环依赖问题。
方法注入
工厂方法注入
使用p命名空间
xmlns:p="http://www.springframework.org/schema/p"
bean id="test" class="com.example.demo.dao.BeanTest"
p:a="use namespace p"/>
p:a="use namespace p"/>
装配Bean
自动装配
Spring IoC 容器知道所有Bean的配置信息,此外,通过Java反射机制还可以获知实现类的结构信息,如构造函数方法的结构、属性等信息。掌握所有Bean的这些信息后,SpringIoC容器就可以按照某种规则对容器中的Bean进行自动装配,而无须通过显式的方式进行依赖配置。Spring 为厌恶配置的开发人员提供了一种轻松的方法,可以按照某些规则进行Bean的自动装配。
byName
根据名称进行自动匹配。假设Boss有一个名为car的属性,如果容器中刚好有一个名为car的Bean,Spring就会自动将其装配给Boss的car属性
byType
根据类型进行自动匹配。假设Boss有一个Car类型的属性,如果容器中刚好有一个Car类型的Bean, Spring 就会自动将其装配给Boss的这个属性
constructor
与ByType类似,只不过它是针对构造函数注入而言的。如果Boss有一一个构造函数,构造函数包含一个Car类型的入参,如果容器中有一个Car类型的Bean,则Spring 将自动把这个Bean作为Boss构造函数的入参;如果容器中没有找到和构造函数入参匹配类型的Bean,则Spring将抛出异常
autodetect
根据Bean的自省机制决定采用byType还是constructor进行自动装配。如果Bean提供了默认的构造函数,则采用byType;否则采用constructor
<beans>元素标签中的default-autowire属性可以配置全局自动匹配,default-autowire属性的默认值为no,表示不启用自动装配;其他几个可选配置值分别为byName、byType、constructor和autodetect, 这几个配置值的含义是不言自明的。不过在<beans>中定义的自动装配策略可以被
<bean>的自动装配策略覆盖。自动装配以四两拨千斤的方式完成容器中Bean 之间的装配工作,这种省心省力的自动装配机制确实省却了大量配置工作。在实际开发中,XML配置方式很少启用自动装配功能,而基于注解的配置方式默认采用byType自动装配策略。
<bean>的自动装配策略覆盖。自动装配以四两拨千斤的方式完成容器中Bean 之间的装配工作,这种省心省力的自动装配机制确实省却了大量配置工作。在实际开发中,XML配置方式很少启用自动装配功能,而基于注解的配置方式默认采用byType自动装配策略。
基于注解的配置
Spring 从2.0开始就引入了基于注解的配置方式,在2.5时得到了完善,在4.0时进一步增强。
使用注解定义Bean
@Component
它可以被Spring容器识别,Spring容器自动将POJO转换为容器管理的Bean。
这些注解的值不写会默认将id设置为类的首字母小写
@Repository
用于Dao实现类进行标注
@Service
用于Service实现类进行标注
@Controller
用于Controller实现类进行标注
之所以要在@Component之外提供这3个特殊的注解,是为了让标注类本身的用途清晰化,完全可以用
@Component替代这3个特殊的注解。但是,推荐使用特定的注解标注特定的Bean,毕竟这样一
眼就可以看出Bean的真实身份。
@Component替代这3个特殊的注解。但是,推荐使用特定的注解标注特定的Bean,毕竟这样一
眼就可以看出Bean的真实身份。
扫描注解定义的Bean
1、添加命名空间:xmlns:context="http://www.springframework.org/schema/context
2、然后就可以在xsi:schemaLocation中添加
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/context/spring-context-4.0.xsd
3、<context:component-scan base-package=""/>
使用注解自动装配
@Autowired
@Autowired 可以对类成员变量及方法的入参进行标注,默认按类型匹配注入
required属性
如果容器中没有一个和标注变量类型匹配的Bean,那么Spring容器启动时将报NoSuchBeanDefinitionException异常。如果希望Spring即使找不到匹配的Bean完成注入也不要抛出异常,那么可以使用@Autowired(required=false)进行标注在默认情况下, @Autowired的required属性值为ture,即要求必须找到匹配的Bean,否则将报异常。
@Qualifier
指定注入Bean的名称,如果容器中有一个以上匹配的Bean时,则可以通过@Qualifier注解限定Bean的名称
如果一个方法拥有多个入参,Spring允许对方法入参标注@Qualifier以指定注入Bean的名称
对集合类进行标注
如果对类中集合类的变量或方法入参进行@Autowired标注,那么Spring会将容器中类型匹配的所有Bean都自动注入进来。在默认情况下,这些Bean的加载顺序是不确定的,在Spring4.0中可以通过@Order注解或实现Ordered接口来决定Bean加载的顺序,值越小,优先被加载。
延迟依赖注入
Spring 4.0 支持延迟依赖注入,即在Spring 容器启动的时候,对于在Bean上标注@Lazy及@Autowired注解的属性,不会立即注入属性值,而是延迟到调用此属性的时候才会注入属性值
注:对Bean 实施延迟依赖注入,@Lazy 注解必须同时标注在属性及目标Bean上,二者缺一,则延迟注入无效。
对标准注解的支持
下别两个与@Autowired注解的功用类似
JSR-250
@Resource
默认按名字匹配注入
要求提供一个 Bean名称的属性,如果属性为空,则自动采用标注处的变量名或方法名作为Bean的名称
JSR-330
@Inject
和@Autowired一样,默认按类型匹配注入
但没有required属性
可见,不管是@Resource还是@Inject注解,其功能都没有@Autowired丰富,因此,除非必要,大可不必在乎这两个注解。
Bean作用范围及生命过程方法
基于Java类的配置
定义Bean
JavaConfig是Spring的一个子项目,它旨在通过Java类的方式提供Bean的定义信息,该项目早在Spring 2.0时就已经发布了
1.0 版本。Spring 4.0基于Java类配置的核心就取材于JavaConfig, JavaConfig 经过若干年的努力终于修成正果,成为
Spring 4.0的核心功能。
1.0 版本。Spring 4.0基于Java类配置的核心就取材于JavaConfig, JavaConfig 经过若干年的努力终于修成正果,成为
Spring 4.0的核心功能。
普通的POJO只要标注@Configuration注解,就可以为Spring容器提供Bean定义的信息,每个标注了@Bean的类方法都相当于提供了一个Bean的定义信息
使用条件
由于Spring容器会自动对@Configuration的类进行“ 改造”,以植入Spring容器对Bean的管理逻辑,所以使用基于Java类的配置必须保证将
Spring aop类包和CGLIB类包加载到类路径下。
Spring aop类包和CGLIB类包加载到类路径下。
Bean的类型由方法返回值的类型决定,名称默认和方法名相同,也可以通过入参显式指定Bean名称,如
@Bean(name= "userDao")。@Bean 所标注的方法体提供了Bean 的实例化逻辑。
@Bean(name= "userDao")。@Bean 所标注的方法体提供了Bean 的实例化逻辑。
引用不同配置类的Bean
由于@Configuration注解类本身已经标注了@Component注解,所以任何标注了@Configuration的类,本身也相当于标注了@Component,即它们可以像普通的Bean一样被注入其他Bean中。
三种方式的比较
基于Java类的配置方式通过代码编程的方式可以更加灵活地实现Bean的实例化及Bean之间的装配;
另两者都是通过配置声明的方式,在灵活性上要稍逊一些,但在配置上要更简单一些。
另两者都是通过配置声明的方式,在灵活性上要稍逊一些,但在配置上要更简单一些。
注入参数
注入参数可以为
字面值
引用其他Bean
内部Bean
null值
<null/>
级联属性
集合类型属性
Properties
Map
List
Set
强类型集合
集合合并
整合多个配置文件
AOP
简介
Spring AOP是AOP技术在Spring中的具体实现,它是构成Spring框架的另一个重要基石。Spring AOP构建于IoC之上,和IoC“浑然天成”,统一于Spring容器之中。
AOP是Aspect Oriented Programing 的简称,最初被译为“面向方面编程”,这个翻译向来为人所诟病,但是由于先入为主的效应,受众广泛,所以这个翻译依然被很多人使用。但我们更倾向于用“面向切面编程”的译法,因为它更加达意。
按照软件重构思想的理念,如果多个类中出现相同的代码,则应该考虑定义一个父类,将这些相同的代码提取到父类中。比如Horse、Pig、Camel这些对象都有run()和eat()方法,通过引入一个包含这两个方法的抽象的Animal父类,Horse、 Pig、 Camel 就可以通过继承Animal复用run()和eat()方法。通过引入父类消除多个类中重复代码的方式在大多数情况下是可行的,但世界并非永远这样简单。
对于一些事务它周围会环绕记录日志,性能检测等事务,如:事务开始前要记录一次日志,结束后又要记录一次日志,这种重复的代码就无法通过纵向继承来处理。监视和事务管理这些非业务性代码葛藤缠树般包围着业务性代码。
AOP独辟蹊径,通过横向抽取机制为这类无法通过纵向继承体系进行抽象的重复性代码提供了解决方案。Java语言本身不直接提供这种横向抽取的能力。
AOP的实现者
AspectJ
AspectJ是语言级的AOP实现,2001 年由Xerox PARC的AOP小组发布。AspectJ 扩展了Java 语言,定义了AOP语法,能够在编译期提供
横切代码的织入,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
横切代码的织入,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
AspectWerkz
AspectWerkz是基于Java的简单、动态、轻量级的AOP框架,该框架于2002年发布,由BEA Systems提供支持。它支持运行期或类装载期织入横切代码,所以它拥有一个特殊的类装载器。现在,AspectJ 和AspectWerkz项目已经合并,以便整合二者的力量和技术创建统一的 AOP平台。它们合作的第一一个发布版本是AspectJ 5:扩展AspectJ语言,以基于注解的方式支持类似AspectJ的代码风格。
Jboss AOP
JBoss AOP于2004年作为JBoss应用程序服务器框架的扩展功能发布
Spring AOP
Spring AOP使用纯Java实现,它不需要专门的编译过程,也不需要特殊的类装载器,它在运行期通过代理方式向目标类织入增强代码。Spring并不尝试提供最完整的AOP实现,相反,它侧重于提供一种和SpringIoC容器整合的AOP实现,用以解决企业级开发中的常见问题。在Spring中可以无缝地将Spring AOP、IoC 和AspectJ 整合在一起。
AOP术语
连接点(Joinpoint)
特定点是程序执行的某个特定位置,如类开始初始化前、类初始化后、类的某个方法调用前/调用后、方法抛出异常后。一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就被称为“连接点”。Spring 仅支持方法的连接点,即仅能在方法调用前、方法调用后、方法抛出异常时及方法调用前后这些程序执行点织入增强。我们知道,黑客攻击系统需要找到突破口,没有突破口就无法进行攻击。从某种程度上来说,AOP也可以看成一个黑客(因为它要向目前类中嵌入额外的代码逻辑),连接点就是AOP向目标类打入楔子的候选锚点。
连接点由两个信息确定:一是用方法表示的程序执行点;二是用相对位置表示的方位。如在Test.foo()方法执行前的连接点,执行点为
Test.foo(),方位为该方法执行前的位置。Spring使用切点对执行点进行定位,而方位则在增强类型中定义。
Test.foo(),方位为该方法执行前的位置。Spring使用切点对执行点进行定位,而方位则在增强类型中定义。
切点(Pointcut)
每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点,即连接点是程序类中客观存在的事物。但在为数众多的连接点中,如何定位某些感兴趣的连接点呢?AOP通过“切点”定位特定的接连点。借助数据库查询的概念来理解切点和连接点的关系再合适不过了:连接点相当于数据库中的记录,而切点相当于查询条件。切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
在Spring 中,切点通过org.springframework aop.Pointcut接口进行描述,它使用类和方法作为连接点的查询条件,SpringAOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。确切地说,应该是执行点而非连接点,因为连接点是方法执行前、执行后等包括方位信息的具体程序执行点,而切点只定位到某个方法上,所以如果希望定位到具体的连接点上,还需要提供方位信息。
增强(Advice)
增强是织入目标类连接点上的一段程序代码,是不是觉得AOP越来越像黑客了,这不是往业务类中装入木马吗?我们大可按照这一思路去理解增强,因为这样更形象易懂。在Spring中,增强除用于描述一段程序代码外, 还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点的方位信息和切点信息,就可以找到特定的连接。正因为增强既包含用于添加到目标连接点上的一-段执行逻辑,又包含用于定位连接点的方位信息,所以Spring 所提供的增强接口都是带方位名的,如BeforeAdvice 、AfterReturningAdvice、ThrowsAdvice 等。BeforeAdvice 表示方法调用前的位置,而AfterReturningAdvice表示访问返回后的位置。所以只有结合切点和增强,才能确定特定的连接点并实施增强逻辑。
目标对象(Target)
增强逻辑的织入目标类。
引介(Introduction)
引介是-种特殊的增强,它为类添加一些属性和方法。这样,即使-一个业务类原本没有实现某个接口,通过AOP的引介功能,也可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
织入(Weaving)
织入是将增强添加到目标类的具体连接点上的过程。AOP就像一台织布机,将目标类、增强或者引介天衣无缝地编织到一起。我们不能不说“织入”这个词太精辟了。
根据不同的实现技术,AOP 有3种织入方式:
根据不同的实现技术,AOP 有3种织入方式:
- 编译期织入,这要求使用特殊的Java编译器。
- 类装载期织入,这要求使用特殊的类装载器。
- 动态代理织入,在运行期为目标类添加增强生成子类的方式。
代理(Proxy)
一个类被AOP织入增强后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以可以采用与调用原类相同的方式调用代理类。
切面(Aspect)
切面由切点和增强(引介)组成,它既包括横切逻辑的定义,也包括连接点的定义。SpringAOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入切面所指定的连接点中。
AOP的工作重心在于如何将增强应用于目标对象的连接点上。这里包括两项工作:
- 如何通过切点和增强定位到连接点上;
- 如何在增强中编写切面的代码。
使用Spring AOP
创建增强类
Spring使用增强类定义横切逻辑,同时由于Spring只支持方法连接点,增强还包括在方法的哪一点加入横切代码的方位信息,所以增强既包含横切逻辑,又包含部分连接点的信息。
前置增强
BeforeAdvice
因为Spring只支持方法级的增强,所以MethodBeforeAdvice是目前可用的前置增强,表示在目标方法执行前实施增强,而BeforeAdvice是为了将来版本扩展需要而定义的。
MethodBeforeAdvice接口仅定义了唯一的方法:
before(Method method, Object[] args, Object obj) throws Throwable。
其中,method 为目标类的方法; args 为目标类方法的入参;而obj为目标类实例。当该方法发生异常时,将阻止目标类方法的执行。
before(Method method, Object[] args, Object obj) throws Throwable。
其中,method 为目标类的方法; args 为目标类方法的入参;而obj为目标类实例。当该方法发生异常时,将阻止目标类方法的执行。
后置增强
AfterReturningAdvice
环绕增强
MethodInterceptor
异常抛出增强
ThrowsAdvice
引介增强
IntroductionInterceptor
这些增强接口都有一些方法,通过实现这些接口方法,并在接口方法中定义横切逻辑,就可以将它们织入目标类方法的相应连接点位置。
创建代理
通过增强类和目标使用ProxyFactory生成代理类(可使用IoC直接注入)
自动创建代理
创建切面
只通过上边的增强类,增强会被织入目标类的所有方法中。假设我们希望有选择地织入目标类的某些特定方法中,就需要使用切点进行目标连接点的定位。
切点
Pointcut接口
Pointcut由ClassFilter和MethodMatcher构成,它通过ClassFiter定位到某些特定类上,通过MethodMatcher
定位到某些特定方法上,这样Pointcut 就拥有了描述某些类的某些特定方法的能力。
定位到某些特定方法上,这样Pointcut 就拥有了描述某些类的某些特定方法的能力。
主要包
org.springframework.aop.support
切点类型
静态方法切点
动态方法切点
注解切点
表达式切点
流程切点
复合切点
切面
由于增强既包含横切代码,又包含部分连接点信息(方法前、方法后主方位信息),所以可以仅通过增强类生成一个切面。但切点仅代表目标类连接点的部分信息(类和方法的定位),所以仅有切点无法制作出一个切面,必须结合增强才能制作出切面。Spring使用org.springframework.aop.Advisor接口表示切面的概念,一个切面同时包含横切代码和连接点信息。
切面类型
一般切面
Advisor
具有切点的切面
PointcutAdvisor
引介切面
IntroductionAdvisor
SpringAOP的实现原理
Spring AOP使用动态代理技术在运行期织入增强的代码,Spring AOP使用了两种代理机制:一种是基于JDK的动态代理;另一种是基于CGLib的动态代理。之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理。
JDK动态代理
CGLIB动态代理
Events
Resources
i18n
i8n(其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。 在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。通常与i18n相关的还有L10n(“本地化”的简称)。
Validation
Data Binding
Type Conversion
SpEL
Web Servlet
Spring MVC
简介
大部分Java应用都是Web应用,展现层是Web应用不可忽略的重要环节。Spring为展现层提供了一个优秀的Web框架——Spring MVC。和众多其他的Web框架一样,它基于MVC的设计理念。此外,它采用了松散耦合、可插拔的组件结构,比其他的MVC框架更具扩展性和灵活性。
Spring MVC通过一套MVC注解,让POJO成为处理请求的控制器,无须实现任何接口。同时,Spring MVC还支持REST风格的URL请求:注解驱动及REST风格的Spring MVC是Spring的出色功能之一。此外,Spring MVC在数据绑定、视图解析、本地化处理及静态资源处理上都有许多不俗的表现。它在框架设计、扩展性、灵活性等方面全面超越了Struts、WebWork等MVC框架,从原来的追赶者一跃成为MVC的领跑者。
Spring MVC通过一套MVC注解,让POJO成为处理请求的控制器,无须实现任何接口。同时,Spring MVC还支持REST风格的URL请求:注解驱动及REST风格的Spring MVC是Spring的出色功能之一。此外,Spring MVC在数据绑定、视图解析、本地化处理及静态资源处理上都有许多不俗的表现。它在框架设计、扩展性、灵活性等方面全面超越了Struts、WebWork等MVC框架,从原来的追赶者一跃成为MVC的领跑者。
Spring MVC框架围绕DispatcherServlet这个核心展开,DispatcherServlet是SpringMVC的总导演、总策划,它负责截获请求并将其分派给相应的处理器处理。SpringMVC框架包括注解驱动控制器、请求及响应的信息处理、视图解析、本地化解析、上传文件解析、异常处理及表单标签绑定等内容。
注解驱动控制器
文件上传
WebSocket
SockJS
STOMP Messaging
Spring Boot
Spring Cloud
0 条评论
下一页