Email:[email protected]
Blog:http://blog.csdn.net/LzwGlory
先了解下基础知识
Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如 EHCache 集成。
其特点总结如下:
上图显示,当客户端“Calling code”调用一个普通类 Plain Object 的 foo() 方法的时候,是直接作用在 pojo 类自身对象上的,客户端拥有的是被调用者的直接的引用。
而 Spring cache 利用了 Spring AOP 的动态代理技术,即当客户端尝试调用 pojo 的 foo()方法的时候,给他的不是 pojo 自身的引用,而是一个动态生成的代理类
如上图所示,这个时候,实际客户端拥有的是一个代理的引用,那么在调用 foo() 方法的时候,会首先调用 proxy 的 foo() 方法,这个时候 proxy 可以整体控制实际的 pojo.foo() 方法的入参和返回值,比如缓存结果,比如直接略过执行实际的 foo() 方法等,都是可以轻松做到的。
1.Ehcache可以对页面、对象、数据进行缓存,同时支持集群/分布式缓存。如果整合Spring、Hibernate也非常的简单,Spring对Ehcache的支持也非常好。EHCache支持内存和磁盘的缓存,支持LRU、LFU和FIFO多种淘汰算法,支持分布式的Cache,可以作为Hibernate的缓存插件。同时它也能提供基于Filter的Cache,该Filter可以缓存响应的内容并采用Gzip压缩提高响应速度。
2. Spring 的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如 EHCache 集成。
其特点总结如下:
下面介绍下:JAR包的功能介绍:
Spring-core.jar:
这个jar文件包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
spring-beans.jar:
这个jar文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有类。
springIoC(依赖注入)的基础实现
如果应用只需基本的IoC/DI支持,引入spring-core.jar及spring-beans.jar文件就可以了。
spring-context-support.jar:
spring-context 的扩展支持,包含支持缓存Cache(ehcache)、JCA、JMX、邮
件服务(Java Mail、COS Mail)、任务计划Scheduling(Timer、Quartz)方面的类。
spring-context.jar:
spring 提供在基础 IoC 功能上的扩展服务,此外还提供许多企业级服务的支持,如 邮件
服务、任务调度、JNDI定位、EJB 集成、远程访问、 缓存以及各种视图层框架的封装等。
还有对于Application的支持
spring-expression.jar:
spring 表达式语言也就是 spel表达式
spring-test.jar:
spring 对Junit 等测试框架的简单封装。
commons-logging.jar:
是使用Spring-core.jar的必备包
slf4j-api:
slf4j-api本质就是一个接口定义。
slf4j-log4j12:
链接slf4j-api和log4j中间的适配器
log4j:
这个是具体的日志系统。通过slf4j-log4j12初始化Log4j,达到最终日志的输出。
junit:
测试工具
hamcrest-core:
是junit的依赖包,在4.11这个版本里,不包含这个包,4.8版本就不需要这个包
spring-aop:
是spirng-context的依赖包,因为springCache也采用AOP的原理
介绍一些常用Maven插件:
1. maven-dependency-plugin:
maven-dependency-plugin最大的用途是帮助分析项目依赖,dependency:list能够列出项目最终解析到的依赖列表,dependency:tree能进一步的描绘项目依赖树,dependency:analyze可以告诉你项目依赖潜在的问题,如果你有直接使用到的却未声明的依赖,该目标就会发出警告。maven-dependency-plugin还有很多目标帮助你操作依赖文件,例如dependency:copy-dependencies能将项目依赖从本地Maven仓库复制到某个特定的文件夹下面。
2. maven-compiler-plugin:
<!-- compiler插件, 设定JDK版本 -->
3. maven-war-plugin:
<!-- war插件用于打包成war项目 -->
使用maven-war-plugin这个插件可以在执行打包命令的时候指定我要打哪个环境的包, 而不需要去关注我现在要用什么配置文件了.当然只适用于Maven项目.
既然是web项目,就需要打war包,那就需要这个插件
4. maven-resources-plugin:
<!-- resource插件, 设定编码 -->
maven-compiler-plugin用来编译Java代码,maven-resources-plugin则用来处理资源文件。默认的主资源文件目录是src/main/resources,很多用户会需要添加额外的资源文件目录,这个时候就可以通过配置maven-resources-plugin来实现。此外,资源文件过滤也是Maven的一大特性,你可以在资源文件中使用${propertyName}形式的Maven属性,然后配置maven-resources-plugin开启对资源文件的过滤,之后就可以针对不同环境通过命令行或者Profile传入属性的值,以实现更为灵活的构建。
xml、properties文件都是资源文件,编码的时候遇到中文总要进行转码!用什么编码?UTF-8,那就记得强制
5. maven-source-plugin:
<!-- 源码插件 -->
maven-source-plugin提供项目自动将源码打包并发布的功能
6. maven-clean-plugin:
清除target 文件夹下由install产生的一些东西例如 war
7. maven-install-plugin:
用于自动安装项目的主要工件(JAR、WAR或EAR),其POM和任何附加构件(来源、javadoc等)所产生的一个特定的项目。
加入: xmlns:p="http://www.springframework.org/schema/p"
<context:annotation-config /> <context:component-scan base-package="com.lzw" /> <!-- 自动扫描所有注解该路径 --> <!--start spring缓存 --> <cache:annotation-driven /><!-- 支持缓存的配置项 --> <!--start 一般的spring_ehcache缓存管理 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/> <!-- EhCache library setup --> <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="classpath:ehcache.xml" p:shared="true"/> <!-- 保持使用p:shared="true"同一个缓存 --> <!--end 一般的spring_ehcache缓存管理 --> <!--end spring缓存 -->
@Service("EhcacheServiceImpl") public class EhcacheServiceImpl{ @Cacheable(value="queryCache",key="#idCardOrghCard+'checkIdCardOrghCard'") public String checkIdCardOrghCard(String idCardOrghCard) { // TODO Auto-generated method stub System.out.println("测试执行方法"); return idCardOrghCard; }
分析下:
@Cacheable注解可以用在方法或者类级别。当他应用于方法级别的时候,只缓存当前方法的返回值。当应用在类级别的时候,这个类的所有方法的返回值都将被缓存。
@Cacheable(value="queryCache",key="#idCardOrghCard+'checkIdCardOrghCard'")
queryCache指的是ehcache.xml里的缓存名字
#idCardOrghCard 用的是Spring的spel表达式
意思就是可以取到
public String checkIdCardOrghCard(String idCardOrghCard) {}
这个方法里,参数所传递过来的值
然后加上方法名'checkIdCardOrghCard' 这样可以保证唯一性,保证唯一性,可以对后续的缓存管理有帮助,缓存的管理后续会讲!!请关注我的博客
<cache name="queryCache" maxElementsInMemory="2000" eternal="false"
timeToIdleSeconds="900" timeToLiveSeconds="1800" overflowToDisk="true" />
ehcache参数的含义:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class EhcacheTest { @Resource private ApplicationContext ctx; @Test public void test1(){ EhcacheServiceImpl EhcacheServiceImpl=ctx.getBean("EhcacheServiceImpl",EhcacheServiceImpl.class); System.out.println(EhcacheServiceImpl.checkIdCardOrghCard("111"));//第一次走数据库 System.out.println(EhcacheServiceImpl.checkIdCardOrghCard("111"));//第二次不走数据库,走缓存 }}
log4j.rootLogger=off, A1 log4j.appender.A1.layout=org.apache.log4j.PatternLayout log4j.appender.A1.layout.ConversionPattern=>>> %d %5p [%l]- %m%n log4j.appender.A1=org.apache.log4j.ConsoleAppender
我默认设置成off 如果想看信息改成 info或debug
来看看log4j参数含义:
log4j.rootLogger=off,A1
Off: 最高等级,用于关闭所有日志记录
Fatal: 指出每个严重的错误事件将会导致应用程序的退出。
Error: 指出虽然发生错误事件,但仍然不影响系统的继续运行。
Warn: 表明会出现潜在的错误情形
Info: 一般用在粗粒度级别上,强调应用程序的运行全程
Debug: 一般和在粗粒度级别上,强调应用程序的运行全程。
All: 最低等级,用于打开所有日志记录。
Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。
log4j.appender.A1=org.apache.log4j.ConsoleAppender
Log4j提供的appender有以下几种:
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(文件)
org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生新文件)
org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
Log4j提供的layout有以下几种:
org.apache.log4j.HTMLLayout(以HTML表格形式布局),
org.apache.log4j.PatternLayout(可以灵活地指定布局模式),
org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),
org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
log4j.appender.A1.layout.ConversionPattern=>>> %d %5p [%l]- %m%n
如果采用了PatternLayout, 则Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“rn”,Unix平台为“n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%: 输出一个”%”字符 %F: 输出日志消息产生时所在的文件名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信息
%n: 输出一个回车换行符,Windows平台为”\r\n”,Unix平台为”\n”输出日志信息换行 可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。
下面看下运行结果:
-------------第一次--------------------
测试执行方法
111
-------------第二次--------------------
111
-------------第三次--------------------
测试执行方法
222
-------------第四次--------------------
222
从结果可以看出来
第一次走了方法,执行了System.out.println("测试执行方法"); 然后把返回的值加载到缓存中
第二次没有走方法,而是直接走了缓存,所以直接返回了缓存值而没有走方法
<!--start 页面缓存 --> <filter> <filter-name>indexCacheFilter</filter-name> <filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class> </filter> <filter-mapping> <filter-name>indexCacheFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--end 页面缓存 --> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list>