(Eclipse+Tomcat7+JDK1.7+Redis )
【为了“着急找答案”的同胞们,我直接把总结放置Top,若想看分析,可以往下翻】
总结:
在配置文件中,不可缺少:
<beans xmlns:cache="http://www.springframework.org/schema/cache"
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.2.xsd"><cache:annotation-driven cache-manager="cacheManager"/>
异常出现原因:
为了使用@Cacheable、@CachePut、@CacheEvict等缓存注解,配置文件就必须要配置Cache,配置之后,我运行Tomcat后,没有做什么(没有加载页面),控制台就出现了报错。。。
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
java.lang.IllegalStateException: No CacheResolver specified, and no bean of type CacheManager found. Register a CacheManager bean or remove the @EnableCaching annotation from your configuration.
at org.springframework.cache.interceptor.CacheAspectSupport.afterSingletonsInstantiated(CacheAspectSupport.java:217)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:795)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
处理配置了Cache,还多了RedisCacheConfig 类(这是因为在配置里,有这个bean,才新建对应RedisCacheConfig 类):
package qiu.ht.base;
import java.lang.reflect.Method;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
@Configuration
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
private volatile JedisConnectionFactory mJedisConnectionFactory;
private volatile RedisTemplate<String, String> mRedisTemplate;
private volatile RedisCacheManager mRedisCacheManager;
public RedisCacheConfig() {
super();
}
public RedisCacheConfig(JedisConnectionFactory mJedisConnectionFactory, RedisTemplate<String, String> mRedisTemplate, RedisCacheManager mRedisCacheManager) {
super();
this.mJedisConnectionFactory = mJedisConnectionFactory;
this.mRedisTemplate = mRedisTemplate;
this.mRedisCacheManager = mRedisCacheManager;
}
public JedisConnectionFactory redisConnectionFactory() {
return mJedisConnectionFactory;
}
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
return mRedisTemplate;
}
public CacheManager cacheManager(RedisTemplate<?, ?> redisTemplate) {
return mRedisCacheManager;
}
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object arg0, Method arg1, Object... arg2) {
StringBuilder sb = new StringBuilder();
sb.append(arg0.getClass().getName());
sb.append(arg1.getName());
for (Object obj : arg2) {
sb.append(obj.toString());
}
System.out.println("sb="+sb);
return sb.toString();
}
};
}
}
我注意到异常中出现:(@EnableCaching该注解有使用于上面这个RedisCacheConfig 类中)
处理了一下,没有用:
“ 我将Cache有关的配置代码<bean>,都 '剪切Ctrl+X' 了,留下这个RedisCacheConfig 类,并且重新运行Tomcat,还是报这个错”——当然还会报这个错,因为这个类是为了对应配置文件才创建的,没了对应配置,留这个类也是有问题的!!!所以我撤回被剪切的代码,接着出现下面这个异常:
严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'redisTemplate' defined in URL [file:/F:/ALL_Course/10Activiti/Ecli/.metadata/.plugins/org.eclipse.wst.server.core/tmp4/wtpwebapps/RedisQ/WEB-INF/classes/spring-redis-context.xml]: Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonProcessingException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getDeclaredMethods(Unknown Source)
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:612)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:510)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors(AutowiredAnnotationBeanPostProcessor.java:244)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors(AbstractAutowireCapableBeanFactory.java:1069)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1042)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:299)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:122)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
... 20 more
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.JsonProcessingException
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
... 36 more
严重: Servlet.service() for servlet [dispatcher] in context with path [/RedisQ] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No cache could be resolved for 'Builder[public void qiu.ht.service.Emp_DepService.add(qiu.ht.vo.Emp_DepVo)] caches=[] | key='#dep.getDepId()' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless=''' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@8a1b1b'. At least one cache should be provided per cache operation.] with root cause
java.lang.IllegalStateException: No cache could be resolved for 'Builder[public void qiu.ht.service.Emp_DepService.add(qiu.ht.vo.Emp_DepVo)] caches=[] | key='#dep.getDepId()' | keyGenerator='' | cacheManager='' | cacheResolver='' | condition='' | unless=''' using resolver 'org.springframework.cache.interceptor.SimpleCacheResolver@8a1b1b'. At least one cache should be provided per cache operation.
at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:245)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.<init>(CacheAspectSupport.java:671)
at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.java:255)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContexts.<init>(CacheAspectSupport.java:577)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at qiu.ht.service.Emp_DepService$$EnhancerBySpringCGLIB$$ae228610_2.add(<generated>)
at qiu.ht.controller.TestController.handleRequest(TestController.java:47)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
除了这个错误,还出现另外错误:
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hgf8cha0xeat2hgkvq7g|1892482, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hgf8cha0xeat2hgkvq7g|1892482, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
一月 23, 2019 9:43:47 上午 org.apache.catalina.core.StandardWrapperValve invoke
严重: Servlet.service() for servlet [dispatcher] in context with path [/RedisQ] threw exception [Request processing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1011E:(pos 8): Method call: Attempted to call method getDepIds() on null context object] with root cause
org.springframework.expression.spel.SpelEvaluationException: EL1011E:(pos 8): Method call: Attempted to call method getDepIds() on null context object
at org.springframework.expression.spel.ast.MethodReference.throwIfNotNullSafe(MethodReference.java:144)
at org.springframework.expression.spel.ast.MethodReference.getValueRef(MethodReference.java:73)
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:66)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:87)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242)
at org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.key(CacheOperationExpressionEvaluator.java:117)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:738)
at org.springframework.cache.interceptor.CacheAspectSupport.generateKey(CacheAspectSupport.java:554)
at org.springframework.cache.interceptor.CacheAspectSupport.collectPutRequests(CacheAspectSupport.java:525)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:424)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655)
at qiu.ht.service.Emp_DepService$$EnhancerBySpringCGLIB$$e43b36fe_2.add(<generated>)
at qiu.ht.controller.TestController.handleRequest(TestController.java:47)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
分析:
因为使用Cache注解,传key时,不能赋整型值!!!所以,我就在Javabean中加depIds变量,怎么就变这样了??(原来,做不做这操作都是会报这个问题,因为错,错在配置文件上少了些什么。。。)
原来自己疏忽了,在测试某异常时,删了Cache某些配置代码,忘了撤消全部“代码”,只是撤消了部分,使得后面报错!!!
解决:
(我少了:<cache:annotation-driven cache-manager="cacheManager"/>)若要使用@Cacheable、@CachePut、@CacheEvict等缓存注解, 以下红框里的代码,都是必不可少的!!!
之后,成功放入redis中作缓存:
代码:
spring-redis-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<description>redis 相关类 Spring 托管</description>
<!--载入 redis 配置文件-->
<context:property-placeholder location="classpath:redis.properties" ignore-unresolvable="true"/>
<!-- 配置 JedisPoolConfig 实例 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}"/>
<property name="maxTotal" value="${redis.maxActive}"/>
<property name="maxWaitMillis" value="${redis.maxWait}"/>
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<!-- 配置JedisConnectionFactory -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.host}"/>
<property name="port" value="${redis.port}"/>
<property name="password" value="${redis.pass}"/>
<property name="database" value="${redis.dbIndex}"/>
<property name="poolConfig" ref="poolConfig"/>
</bean>
<!-- 配置RedisTemplate -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"/>
<!--
因为使用@Cacheable等注解,会传Javabean,在redis有转换成能读取的东西,
则要配keySerializer等属性,但Javabean要先序列化(实现 Serializable)才能让redis转换
-->
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer"/>
</property>
</bean>
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
<constructor-arg ref="redisTemplate"/>
<property name="defaultExpiration" value="3000"/>
<property name="transactionAware" value="true"/>
<property name="usePrefix" value="true"/>
</bean>
<!-- 配置RedisCacheConfig
会自动执行RedisCacheConfig类的keyGenerator(生成key的规则方法)方法,按着里面代码自动操作
-->
<bean id="redisCacheConfig" class="qiu.ht.base.RedisCacheConfig">
<constructor-arg ref="jedisConnectionFactory"/>
<constructor-arg ref="redisTemplate"/>
<constructor-arg ref="cacheManager"/>
</bean>
</beans>
spring-applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!--将redis的配置文件引入进来-->
<import resource="spring-redis-context.xml"/>
<!-- 开启缓存注解功能
若会报错,是因为spring-redis-context.xml配置文件里没有(其实在下面就有讲要加上对应代码)
《bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"》。。。《/。。
-->
<cache:annotation-driven cache-manager="cacheManager"/>
<!-- view处理器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--1 引入属性文件,在配置中占位使用 -->
<context:property-placeholder location="classpath*:db.properties" />
<!--2 配置C3P0数据源 -->
<bean id="datasource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<!--驱动类名 -->
<property name="driverClass" value="${jdbc.driver}" />
<!-- url -->
<property name="jdbcUrl" value="${jdbc.url}" />
<!-- 用户名 -->
<property name="user" value="${jdbc.uid}" />
<!-- 密码 -->
<property name="password" value="${jdbc.pwd}" />
<!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数 -->
<property name="acquireIncrement" value="5"></property>
<!-- 初始连接池大小 -->
<property name="initialPoolSize" value="10"></property>
<!-- 连接池中连接最小个数 -->
<property name="minPoolSize" value="5"></property>
<!-- 连接池中连接最大个数 -->
<property name="maxPoolSize" value="20"></property>
</bean>
<!--3 会话工厂bean sqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="datasource"></property>
<!-- 别名 -->
<property name="typeAliasesPackage" value="qiu.ht.vo"></property>
<!-- sql映射文件路径 -->
<property name="mapperLocations" value="classpath*:qiu/ht/mapper/*.xml"></property>
</bean>
<!--4 自动扫描对象关系映射 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--指定会话工厂,如果当前上下文中只定义了一个则该属性可省去 -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
<!-- 指定要自动扫描接口的基础包,实现接口 -->
<property name="basePackage" value="qiu.ht.mapper"></property>
</bean>
<!--5 声明式事务管理 -->
<!--定义事物管理器,由spring管理事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
<!--支持注解驱动的事务管理,指定事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--6 容器自动扫描IOC组件 -->
<context:component-scan base-package="qiu.ht"></context:component-scan>
<!--7 aspectj支持自动代理实现AOP功能 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<bean id="/test" class="qiu.ht.controller.TestController">
</bean>
</beans>
Emp_DepDAO 接口类
package qiu.ht.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import qiu.ht.vo.Emp_DepVo;
public interface Emp_DepDAO {
Emp_DepVo depById(Emp_DepVo depVo);//也可以是这样的参数(int depId)
void addEdep(Emp_DepVo edepvo);//只是传一个Javabean对象的记录,传值直接用Javabean就够用
void undateEdep(Emp_DepVo edepvo);//修改员工的年龄和状态
void delEdep(String id);//删除员工记录
}
Emp_DepDAO 配置文件【depId为自动递增】
<?xml version="1.0" encoding="UTF-8"?>
<!-- mybatis的dtd文件 -->
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace属性: 用于指定指向那个接口 -->
<mapper namespace="qiu.ht.mapper.Emp_DepDAO">
<select id="depById" resultType="emp_DepVo">
<include refid="select_all"/>
<![CDATA[
where depId=#{depId}
]]>
</select>
<sql id="select_all">
select * from Emp_Dep
</sql>
<insert id="addEdep" parameterType="qiu.ht.vo.Emp_DepVo" >
<selectKey keyProperty="depId" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
</selectKey>
<![CDATA[
insert into Emp_Dep(depName) values(#{depName});
]]>
</insert>
<update id="undateEdep" parameterType="qiu.ht.vo.Emp_DepVo">
<![CDATA[
update Emp_Dep set depName=#{depName} where depId=#{depId};
]]>
</update>
<delete id="delEdep" parameterType="int">
<![CDATA[
delete from Emp_Dep where depId=#{id};
]]>
</delete>
</mapper>
Emp_DepService
package qiu.ht.service;
import qiu.ht.mapper.Emp_DepDAO;
import qiu.ht.vo.Emp_DepVo;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
//加入服务注解,表示这个类是一个服务层,操作数据库的类
//Service类都要加注解,否则报错
@Service
public class Emp_DepService {
@Resource
Emp_DepDAO edDAO;
//通过Id获取一条记录
@Transactional
//key为 "# dep . getDepId()"值,dep是要对应depById方法的参数名
//如果redis数据库中取到了对应的key,方法就不会执行,如果取不定,则到数据库中取值,然后新增到redis中
@Cacheable(value="dep",key="#depName")
public Emp_DepVo depById(String depName){
System.out.println("depById测试");
return null;
}
@Transactional
//新增成功以后,把返回的结果保存的redis缓存数据库中
//value=key的前缀,#result.getDepIds()的result代表方法的返回值,也可以对应参数名,#dep.getDepIds()
@CachePut(value="dep",key="#dep.getDepIds()")
public Emp_DepVo add(Emp_DepVo dep){
edDAO.addEdep(dep);
return dep;
}
@Transactional
@CacheEvict(value="dep",key="#depIds")
public void delete(String depIds){
edDAO.delEdep(depIds);
}
@Transactional
//要修改,key将会是Hash,里面的field-name分别是:depId-13,depName-营销部
@CachePut(key="#dep.getDepId()")
public Emp_DepVo update(Emp_DepVo dep){
edDAO.undateEdep(dep);
return dep;
}
}
TestController控制类
package qiu.ht.controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import qiu.ht.base.RedisTemplateUtil;
import qiu.ht.service.Emp_DepService;
import qiu.ht.vo.Emp_DepVo;
public class TestController implements Controller{
@Resource
RedisTemplate redisTemplate;
@Resource
Emp_DepService depService;
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView mv=new ModelAndView();
mv.setViewName("index");
System.out.println(redisTemplate);
RedisTemplateUtil redis=new RedisTemplateUtil(redisTemplate);
//测试@Cacheable注解
Emp_DepVo dep=new Emp_DepVo();
dep.setDepName("笑话部");
depService.add(dep);
depService.depById("笑话部");
System.out.println(dep);
return mv;
}
}
打印结果:
org.springframework.data.redis.core.RedisTemplate@1eccf7f
一月 23, 2019 11:09:30 上午 com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource getPoolManager
信息: Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 5, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hgf8cha0xhh8eiiqh6vv|1ca9271, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hgf8cha0xhh8eiiqh6vv|1ca9271, idleConnectionTestPeriod -> 0, initialPoolSize -> 10, jdbcUrl -> jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 20, maxStatements -> 0, maxStatementsPerConnection -> 0, minPoolSize -> 5, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> null, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> false, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]