Spring in action记录
最近一段时间重新学习了一遍SPRING,现在对这些笔记整理一下,一来算是对之前的学习有一个交代,二来当是重新学习一次,三来可以留下备份
这次学习中以SPRING IN ACTION 4这学习资料,整书内容包括有:
Spring基础,Springmvc基础,Spring处理和持久化数据,Spring应用程序与其他系统集成;总结中并不包含Spring web flow和Spring security,websocket和jmx相关部分
一、Spring基础
Spring 4初窥:
Spring的4种基本策略:
基于POJO的轻量级和最小侵入性编程
依赖注入和面向接口的松耦合
基于切面和惯例声明式编程
切面模板减少样板式代码
Spring应用中,对象由Spring容器创建和装配,并存在窗口之中
Spring容器可归为2种类型:bean工厂和应用上下文
应用上下文:
AnnotationConfigApplicationContext
AnnotationConfigWebApplicationContext
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
XmlWebApplicationContext
bean生命周期
1、Spring对bean进行实例化
2、Spring将值和bean引用注入bean对应属性中
3、如bean实现了BeanNameAware接口,Spring将bean的ID传递给setBeanName()方法
4、如bean实现了BeanFactoryAware接口,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
5、如bean实现了ApplicationContextAware接口,Spring将调用setApplicationContext方法,将bean所在应用上下文的引用传入进来
6、如bean实现了BeanPostProcessor接口,Spring将调用它们的postProcessBeforeInitialization()方法
7、如bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet()方法,类似,如bean使用init-methon声明初始方法,该方法会被调用
8、如bean实现BeanPostProcessor接口,Spring将调用它们的postProcessAfterInitialization()方法
9、bean装配完毕,直到应用上下文被销毁
10、如bean实现了DisposableBean接口,Spring将调用其destory()方法,如有指定destroy-method,该方法也会被调用
Spring模块:数据访问与集成,web与远程调用,面向切面编程,Instrumentation,Spring核心容器,测试
Bean装配:
1、在XML中显式装配
1、Bean声明
2、Bean注入
1、构造器注入:
1、<constructor-arg>按先后顺序依次装配
2、c-命名空间前缀
2、属性注入:
1、<property>
2、p-命名空间前缀
3、字面量注入:
<value>、<list>、<set>
2、在Java中进行显式配置
1、配置类@Configuration
2、@Bean
3、隐式的Bean发现机制和自动装配
Spring从2个角度实现自动化装配
组件扫描:在配置类@Configuration上使用@ComponentScan
@ConponentScan默认以配置类所在包作为基础包来扫描组件:basePackages={"asd", "qwe "}或basePackageClass={}
自动装配:@Autowired,直接用在属性,方法上
4、导入和混合配置
1、JavaConfig组件扫描和自动装配
创建根配置类,利用@Import,@ImportResource引入其他配置类或文件
@Configuration
@Import(AConfig.class)
@ImportResource("classpath:B.xml")
public class RootConfig{}
2、根配置中
<bean class="AConfig"/>
<import resource="B.xml">
高级装配
Profile
1、 在配置类中的@Bean中使用@Profile(‘XX’),没有指定Profile的Bean始终被创建
2、 XML中给beans标签设置profile属性
Profile激活(spring.profiles.active和spring.profiles.default)
1、 作为DispatcherServlet初始化参数
2、 Web应用上下文参数
3、 JDNI条目
4、 环境变量
5、 JVM系统属性
6、 测试中使用@ActiveProfiles
条件化装配:在@Bean类上使用@Conditional注解,提供实现Condition接口的类
Bean命名冲突
1、@Autowried会根据类型自动装配
2、使用@Primary设定首选
3、使用@Qualifier指定装配的bean
1、为bean设置自定义限定符@Qualifier,并在装配中使用
2、利用@Qualifier创建自定义注解使用
Bean作用域:单例,原型,会话,请求(在会话和请求作用域中,由于作用域不同,要使用代理模式注入)
运行时值注入
1、 属性占位符(${})
a) 为使用占位符,必须配置PropertySourcesPlaceholderConfigurer,形式:@Value(“${}”)
b) 在配置类中使用@PropertySource()为Environment引入资源
2、 Spring表达式(#{})
a) 使用bean id引用bean
b) 调用方法和访问对象属性
c) 对值进行算术,关系和逻辑运算
d) 正则表达式匹配
e) 集合操作
面向切面
切面:具体业务处理和切点的结合
切面:引入和织入
AOP:
1、 声明式AOP
a) XML中<aop:aspectj-autoproxy>
2、 基于注解的AOP
a) JavaConfig在配置类上使用@EnableAspectJAutoProxy
通知:@Before @After @AfterReturn @AfterThrowing @Around
环绕通知接收ProcceedingJoinPoint函数,调用process方法调用
切面方法如有参数传递,需要额外处理
@Aspect
Public class EncoreableIntroducer {
@DeclareParents(value=”concert.Performance+”哪种类型bean要引入该接口 defaultImpl=DefaultEncoreable.class为引入功能提供实现的bean)
Public static Encorable encorable;引入的接口
}
二、SpringMVC基础
搭建SpringMVC
继承AbstractAnnotationConfigDispatcherServletInitializer
重写getServletMappimgs方法,配置DispatcherServlet映射
重写getRootConfigClasses方法,对应ContextLoaderListener创建应用上下文bean
重写getServletConfigclasses方法,创建DispatcherServlet应用上下文bean
@Configguration
@EnableWebMVC
@ComponentScan(“package”)
Public
class WebConfig extends WebMvcConfigurerAdapter{}
传递模型数据到视图
接受请求输入:
查询参数
在控制器方法的形参前使用@RequestParam(value=””, defaultValue=””)
路径变量
在@RequestMapping中映射路径添加占位符${xx}表示路径参数,控制器方法使用@PathVariable(‘xx’)
表单参数
表单校验表单数据对应的POJO添加@Valid Errors处理
校验注解:AssertFalse AssertTrue
DecimalMax DecimalMin
Digits Feture Max Min NotNull
Null Past Pattern Size
视图渲染,SpringMVC提供了ViewResolver接口用于解析逻辑视图,该接口方法返回View实例完成具体渲染
JSP:InternalResourceViewResolver
@Bean
Public
ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
Resolver.setPrefix(“/WEB-INF/views/”);
Resolver.setsuffix(“.jsp”);
Resolver.setViewClass(org.springfamework.web.servlet.view.JstlView.class);
Return
resolver;
}
配置Thymeleaf视图解析器
ThymeleafViewResolver:将逻辑视图名解析为Thymeleaf模板视图
SpringTemplateEngine:处理模板并渲染视图
TemplateResolver:加载Thymeleaf模板,模板引擎
重写AnnotationConfigDispatcherServletInitializer方法实现其他功能
重写customizeRegistration方法借助ServletRegistration.Dynamic对DispatcherServlet进行额外配置,如setMultipartConfig,setInitParameter,setLoadOnStartup
实现Spring的WebApplicationInitializer接口,创建新初始化器就可以添加其他组件
Spring提供多种方法异常转换为响应
1、 特定Spring异常会自动映射为指定的HTTP状态码
2、 异常上添加@responseStatus注解,从而将其映射一个状态码
3、 在方法上可以添加@ExceptionHandler注解
为控制器添加通知(@ControllerAdvice注解的类)
@ExceptionHandler
@InitBinder
@ModelAttribute
跨域重定向中使用flash保存信息
Flash属性保存会话中,然后放到模型中,因此能够在重定向中存活(model.addFlashAttribute)
三、Spring处理和持久化数据
Spring提供了非检查型异常
数据源连接池示例:
@Profile(“qa”)
@Bean
Public
DataSource Data() {
BasicDataSource ds = new BasicDataSource();
Ds.setDriverClassName(“org.he.Driver”);
Ds.setUrl(“jdbc:h2:tcp://localhost/~/spitter”);
Ds.setUsername(“ab”);
Ds.setPassword(“”);
Ds.setInitialSize(5);
Ds.setMaxActive(10);
Return
ds;
}
@Profile(“dev”)
@Bean
Public
DataSource embeddedDataSource() {
Return
new EmbeddedDatabas…().setType(EmbeddedDatabaseType.H2).addScript(“classpath:schema.sql”).addScript(“classpath:test-data.sql”).build();
}
Spring将数据访问过程分为固定和不固定2个不同类:模板,回调
模板管理过程中固定部分,而回调处理自定义数据访问代码(语句,参数绑定和整理结果集)
JdbcOperations是一个接口,定义了JdbcTemplate所有实现操作,其他类似
对象持久化JPA
基于JPA的应用程序 要使用EntityManagerFactory的实现类获取EntityManager实例
EntityManagerFactory:
1
LocalEntityManagerFactoryBean,在persistemce.xml中定义一个或多个持久化单元,持久化单元是同一个数据源下的一个或多个持久化类
2
LocalContainerEntityManagerFactoryBean,在Java配置中设置数据源,JpaVendorAdapter和扫描包
使用Spring会统一管理EntityManager
编写基于JPA的Respository(@Respository, @Transaction)
在Repository中注入EntityManagerFactory(@PesistenceUnti)或EntityManager(@PersistenceContext)处理数据持久化
配置PersistenceAnnotationBeanPostProccessorBean注册Respository
配置PersistenceExceptionTranslationPostProcessor转换异常
借助SpringData实现自动化JPA(JpaRepository, PagingAndSortingRepository, CrudRepository)
在配置类中添加@EnableJpaRespositories(basePackages=””)
SpringData方法名中包含有动作,主题,断言(有多少个限制条件就有多少属性参数)
自定义查询@Query(“sql”)
混合定义
当SpringData JPA为Respository接口生成实现时,会查找名字与接口相同,并且添加Impl后缀的一个类,将类中方法与其生成方法合并一起
使用Redis操作key-value数据
Redis连接工厂会生成Redis数据库服务器的连接:JedisConnectionFactory
Spring
Data Redis提供了2个模板:RedisTemplate StringRedisTemplate
Redis连接工厂和Redis模板要在配置类中提供
当某个条目保存在Redis key-value时,key和value都会使用Redis序列化器进行序列化
缓存数据(caching)
Spring对缓存支持有2种方式:
注解驱动的缓存
1、 配置类中@EnableCaching,创建一个切面并触发Spring注解的切点
2、 配置缓存管理器
a)
配置Redis缓存管理器bean: RedisCacheManager
b)
Redis连接工厂
c)
RedisTemplate
3、 为方法添加注解以支持缓存(Cacheable
CachePut CacheEvict Caching)
4、 自定义缓存key(默认缓存key基于方法参数)
#root.args/caches/target/targetClass/method/methodName/result/Argument
5、条件化缓存 unless
condition
XML声明的缓存
<cache:annotation-driven>
<cache:advice>
<cache:caching>
<cache:cacheable>
<cache:cache-put>
<cache:cache-evit>
<aop:config>
<aop:advisor advice-ref=””
pointcut=”..”>
</acop:config>
<cache:advice id=””>
<cache:caching>
<cache:cacheable>
…
</cache:advice>
四、Spring应用程序和其他系统集成
使用远程服务
远程调用RPC(两者都是同步操作,阻塞调用代码的执行)
远程方法调用RMI
Hessian或Burlap
Http
invoker
JAC-RPC或JAX-WS
在所有的模型中服务都作为Spring所管理的bean配置到应用中,这是通过一个代理工厂bean实现的
服务器端
RMI
RmiServiceExporter把POJO包装到服务适配器中,并把服务适配器绑定到RMI注册表中,从而将POJO转换为RMI服务
@Bean
Public
RmiServiceExporter rmiExporter(SpitterService spitterService) {
RmiServiceExporter rmiExporter =
new RmiServiceExporter();
rmiExporter.setServiceName(‘SpitterService’);
rmiExporter.setServiceInterface(SpitterService.class);
return
rmiExporter;
}
默认使用本地机1099端口注册,使用registeryPort和registryHost属性可指定端口和主机
客户端
@Bean
Punblic RmiProxyFactoryBean spitterService()
{
RmiProxyFactoryBean rmiProxy =
new RmiProxyFactoryBean();
rmiProxy.setServiceUrl(“rmi://localhost/spitterService”);
rmiProxy.setServiceInterface(SpitterService.class);
return
rmiProxy;
}
缺点:RMI端口协商,难穿透防火墙;基于JAVA;序列化机制要求JAVA版本一致
Hession(二进制,RMI也是基于二进制消息), Burlap(XML)基于HTTP
HessionServiceExporter是一个SpringMVC控制器,它可以接收Hessian请求,并把这些请求转换成对POJO调用,从而将POJO导出为一个Hessian服务
导出Hessian服务
@Bean
Public
HessianServiceExporter hessianExportedSpitterService(SpitterService service){
HessianServiceExporter exporter = new HessianServiceExporter();
exporter.setService(service);
exporter.setServiceInterface(SpitterService.class);
return
exporter;
}
配置Hessian控制器
1、 在web.xml中配置Spring的DispatcherServlet,并把应用部署为web应用
2、 在Spring配置文件中配置一个URL处理器,把Hession服务给URL分发给对应Hessian服务bean
导出Burlap服务类似,使用BurlapServiceExporter
访问Hessian/Burlap服务
@Bean
HessianProxyFactoryBean spitterService(){
HessianProxyFactoryBean proxy = new HessianProxyFactoryBean
();
Proxy.setServiceUrl(“??”);
Proxy.setServiceInterface(Spittervice.class);
Return
proxy;
}
类似burlap使用BurlapProxyFactory
HTTP
invoke基于HTTP远程调用,并使用Java序列化机制
HttpInvokerServiceExporter、HttpInvokerProxyFactoryBean
使用和发布web服务
@WebService web服务端点
@WebMethod 操作
对象生命周期不是由Spring管理,而对象又需要注入Spring管理bean时,使用SpringBeanAutoWiringSuport
使用SimpleJaxWsServiceServiceExporter导出服务
客户端代理JAX-WS服务 JaxWsPortProxyFactoryBean
@Bean
Public
JaxWsPortProxyFactoryBean spitterService(){
JaxWsPortFactoryBean proxy = new JaxWsPortProxyFactoryBean();
Proxy.setServiceName(“spitterService”);
Proxy.setPortName(“spitterService”);
Proxy.setServiceInterface(SpitterService.class);
Proxy.setNamespaceUri(“http://spitter.com”);
Return
proxy;
}
使用SpringMVC创建REST
API
RPC是面向服务的,并关注于行为和动作,而REST面向资源,强调描述应用程序的事物和行为
REST是将资源的状态心最合适客户端或服务端的形式从对端转换到另一则
行为描述:
Post create
Get read
Put update
Delete
delete
Spring
REST支持
1、 控制器对HTTP方法支持
2、 参数化URL处理(@PathVariable)
3、 Spring视图和视图解析器处理返回结果
4、 ContentNegotiatingViewResolver选择最合适客户端的表述
5、 @ResponseBody,HttpMethodConverter替换基于视图的渲染方式
6、 @RequestBody,HttpMethodConverter传入参数处理
7、 RestTemplate
Spring提供2种方法将资源的Java表述形式转换为发送给客户端的表述方式
1、 内容协商(不建议使用)
a)
ContentNegotiationViewResolve
i.
确定请求媒体类型
ii.
找到合适请求媒体类型的最佳视图
b)
ContentNegotiatoinManager(注入ContentNegotiationViewResolve)
i.
默认内容类型
ii.
由请求参数指定内容类型
iii.
忽视请求的Accept头部信息
iv.
将请求扩展名映射为类型
v.
JVF
2、 消息转换器
没有模型没有视图,只有控制器产生的数据,以及消息转换器转换数据后产生的资源表述(@ResponseBody)
@RequestMapping(method=RequestMethod.POST
consumes=”application/json”)
Public @ResponseBody
Spittle save(@RequestBody
Spittle spittle) {
Return spittleRepository.save(spittle);
}
使用@RestController为控制器默认设置消息转换器
Spring处理异常
1、 使用@ResponseStatus注解指定状态码
2、 控制器方法可以返回ResponseEntity对象,该对象此时不要使用@ResponseBody标识
3、 异常处理器@ExceptionHandler
此外利用ResponseEntity可在响应头中设置头部信息
REST客户端:RestTemplate
Delete
getForEntity getForObject
postForEntity postForLocation postForObject
put
exchange
使用exchange方法可以设定请求头部
Spring消息
异常消息中2个主要概念,消息代理和目的地
消息代理确保消息被投递到指定目的地
目的地(队列,主题)从何取得,不关注谁取
JMS(Java消息服务) activemq
1、
创建连接工厂<amq:connectionFactory id=”connectionFactory” brokerURL=”tcp://localhost:61616”/>
2、
声明ActiveMQ消息目的地
<amq:queue id=”spittleQueue”
physicalName=”spittle.alert.queue”/>
<amq:topic id=”spittleTopic”
physicalName=”spittle.alert.topic”/>
3、
JmsTemplate
a)
使用convertAndSend在发送时,完成消息转换
b)
类似有receiveAndConvert
JmsTemplate接收信息是同步的,有MDP,消息驱动POJO
消息监听监控JMS目的地并等待消息到达,消息到达时,取出消息传给感兴趣的监听器
<jms:listener-container
connection-factory=”connectionFactory”>
<jms:listener destination=”spitter.alert.queue” ref=”spittleHandler”
method=”handlerSpittleAlert” />
</jms:listener-container>
使用基于消息的RPC
1、 JmsInvokerServiceExporter
2、 JmsInvokerProxyFactoryBean
服务器端
<jms:listener-container
connection-factory=”connectionFactory”>
<jms:listener destination=”spitter.alert.queue”
ref=”alertServiceExporter”/>
</jms:listener-container>
<bean
id=”alertServiceExport”
class=”….JmsInvokerServiceExporter” p:service-ref=”alertService”
p:serviceInterface=”…”/>
客户端
<bean
id=”alertService” class=”….JmsInvokerProxyFactoryBean”
p:connectionFactory-ref=”connectiontory” p:queueName=”spittle.alert.queue” prop:serviceInterface=”…”/>
使用AMQP实现消息功能
消息产生者将消息发布到一个Exchange,Exchange会绑定到一个或多个队列去,将信息路由到队列上,信息的消费者从队列中提取数据并进行处理
AMQP
Exchange(将routing key和队列bingding(与exchange))
Direct:
Topic:
Headers:
Fanout:
生产者将信息发送给Exchange,并带有一个routing key,消费者从队列中取消息
<connection-factory
id=”connectionFactory”/>
在<admin>下
<queue>
<fanout-exchange>
<header-exchange>
<topic-exchange>
<direct-exchange>
<bidings>
<biding/>
<bidings>
RabbitTemplate
ConverAndSend(“exchange”,
“key”, obj)
receiveAndConvert(“queue”)
目标可以设置POJO消息驱动
<jms:listener-container
connection-factory=”connectionFactory”>
<jms:listener ref=”spittleHandler” method=”handlerSpittleAlert”
queuenames=””/>
</jms:listener-container>
或可以queues=”,”
<queue id=”xx” name=”xx”/>
Spring in action记录的更多相关文章
- Spring in Action 4th 学习笔记 之 AOP
前提:本文中的AOP仅限于Spring AOP. 先说说为什么需要AOP 最简单的一个例子就是日志记录,如果想记录一些方法的执行情况,最笨的办法就是修改每一个需要记录的方法.但这,真的很笨... 好的 ...
- Spring In Action 5th中的一些错误
引言 最近开始学习Spring,了解到<Spring实战>已经出到第五版了,遂打算跟着<Spring实战(第五版)>来入门Spring,没想到这书一点也不严谨,才看到第三章就发 ...
- 1、Spring In Action 4th笔记(1)
Spring In Action 4th笔记(1) 2016-12-28 1.Spring是一个框架,致力于减轻JEE的开发,它有4个特点: 1.1 基于POJO(Plain Ordinary Jav ...
- spring in action 4th --- quick start
读spring in action. 环境搭建 quick-start依赖注入 面向切面 1.环境搭建 jdk1.8 gradle 2.12 Intelij idea 2016.2.1 1.1创建一个 ...
- ssh整合随笔(注解方式,Spring 管理action)
Web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...
- Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客
==他的博客应该不错,没有细看 Spring Boot学习记录(二)--thymeleaf模板 - CSDN博客 http://blog.csdn.net/u012706811/article/det ...
- Spring Boot 日志记录 SLF4J
Spring Boot 日志记录 SLF4J 2016年01月12日 09:25:28 阅读数:54086 在开发中打印内容,使用 System.out.println() 和 Log4j 应当是人人 ...
- spring boot 系列学习记录
——初始篇 结束了短学期的课程,初步学习了ssm框架,凭借这些学到的知识完成了短学期的任务-----点餐系统. 通过学长了解到了spring boot ,自己对spring cloud有所耳闻,但是s ...
- 学习spring in action 第一天
这段时间,开始学习java吧,因为C sharp 学习了java的大量语法格式,所以,留意下,就不会错了,java 有的c sharp也有,而且之前我也学习过java的桌面开发,但是一下子上来就要自己 ...
随机推荐
- BlockingQueue<> 队列的作用
BlockingQueue<> 队列的作用 BlockingQueue 实现主要用于生产者-使用者队列 BlockingQueue 实现主要用于生产者-使用者队列,BlockingQueu ...
- 深入理解计算机系统(2.7)------二进制小数和IEEE浮点标准
整数的表示和运算我们已经讲完了,在实际应用中,整数能够解决我们大部分问题.但是某些需要精确表示的数,比如某件商品的价格,某两地之间的距离等等,我们如果用整数表示将会有很大的出入,这时候浮点数就产生了. ...
- 参加Java培训你必须知道的五点真相!
相信大家都有过到招聘网站投简历.找工作的经历.当一份份简历发出三天后,左等右等连一个电话没有等来,心中不免有些失落,有些焦虑.这个时侯,很多培训机构就会纷纷给你打电话以各种名义让你参加各种IT技能培训 ...
- program 1 : python codes for login program(登录程序python代码)
#improt time module for count down puase time import time #set var for loop counting counter=1 #logi ...
- 使用 TUN 设备实现一个简单的 UDP 代理隧道
若要实现在 Linux 下的代理程序,方法有很多,比如看着 RFC 1928 来实现一个 socks5 代理并自行设置程序经过 socks5 代理等方式,下文是使用 Linux 提供的 tun/tap ...
- Quartz源码——JobStore保存JonDetail和Trigger源码分析(一)
我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! {0} :表的前缀 ,如表qrtz_trigger ,{0}== qrtz_ {1}:quartz ...
- (转)深度学习word2vec笔记之基础篇
深度学习word2vec笔记之基础篇 声明: 1)该博文是多位博主以及多位文档资料的主人所无私奉献的论文资料整理的.具体引用的资料请看参考文献.具体的版本声明也参考原文献 2)本文仅供学术交流,非商用 ...
- vue-resource传参数到后端,后端取不到数据的问题
先上一段代码: this.$http.post('xxx',{Search_Text:this.search_text}).then(function(response){ // 响应成功回调 thi ...
- mvc的filter
如果想要记录ajax的请求和输出信息.内部发生异常记录日志.需要登录认证.需要权限判断:那mvc的各种filter可以帮助你实现你想要的.Mvc框架支持5种不同类型的过滤器:我会按照执行顺序进行简单的 ...
- Node.js之循环依赖
在Node.js中有可能会出现循环依赖的问题,在此做一个简单的记录 假如有一个模块A: exports.loaded = false; const b = require('./b'); module ...