在代理模式下,我在缓存 DAO 层中的内部方法时遇到问题。
我知道在代理模式下,只有通过代理传入的外部方法调用才会被拦截。但是,我想避免切换到 AspectJ 模式,并且想知道是否存在其他解决方法。
我在下面显示我的代码,并且想知道我可以添加哪些更改(如果有)以使此过程正常运行。
--注意我正在使用 swagger 来记录我的代码
--另请注意,由于显而易见的原因,我的代码已被淡化......
// Controller
@RestController
@Api(produces = "application/json", protocols = "https", tags = "Securities", description = "Securities information")
public class SecuritiesInfoController extends Controller {
private SecuritiesInfoManager _securitiesInfoManager = new SecuritiesInfoManager();
@RequestMapping(value = "/security", method = RequestMethod.GET)
public List<SecuritiesInfo> getAll(){
return _securitiesInfoManager.getAll();
}
}
//服务
public class SecuritiesInfoManager extends Manager {
private SecuritiesInfoDAO _securitiesDAO = new SecuritiesInfoDAO();
public List<SecuritiesInfo> getAll() {
return _securitiesDAO.getAll();
}
}
//DAO
public class SecuritiesInfoDAO extends DAO {
private static String securitiesTable = "Securities";
@SecuritiesInfoDAOInterface
public List<SecuritiesInfo> getAll() {
//Magic
}
}
//接口(interface)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Cacheable(cacheNames = "SecuritiesInfo",cacheManager="cacheManager",
keyGenerator="keyGenerator" )
public @interface SecuritiesInfoDAOInterface {
}
//缓存配置
@Configuration
//@EnableCaching(mode = AdviceMode.PROXY)
@EnableCaching(proxyTargetClass = true)
//@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
@Bean
public SecuritiesInfoDAO myService() {
// configure and return a class having @Cacheable methods
return new SecuritiesInfoDAO();
}
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
// Defaults
redisConnectionFactory.setHostName("Nope");
redisConnectionFactory.setPort(LoL);
System.out.println("IN CONNTECTION");
redisConnectionFactory.setPassword("Please help me :)");
return redisConnectionFactory;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {
System.out.println("cf: "+cf.toString());
RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
redisTemplate.setConnectionFactory(cf);
return redisTemplate;
}
/*
@Primary
@Bean
public RedisTemplate<String,ExpiringSession> redisTemplate2(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, ExpiringSession> template = new RedisTemplate<String, ExpiringSession>();
template.setHashValueSerializer(new LdapFailAwareRedisObjectSerializer());
template.setConnectionFactory(connectionFactory);
return template;
}
*/
@Bean
public CacheManager cacheManager(RedisTemplate<String, String> redisTemplate) {
System.out.println("IN CACHE MANAGER");
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// Number of seconds before expiration. Defaults to unlimited (0)
// cacheManager.setDefaultExpiration(300);
return cacheManager;
}
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object o, Method method, Object... objects) {
// This will generate a unique key of the class name, the method name,
// and all method parameters appended.
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(method.getName());
for (Object obj : objects) {
sb.append(obj.toString());
}
System.out.println(sb.toString());
return sb.toString();
}
};
}
最佳答案
所以我找到了答案。事实证明我没有正确实现/实例化接口(interface)。
首先,我必须在 Controller 中 @Autowire 我的管理器类。然后在我的管理器中@autowire我的接口(interface)类。
为了获得更详细的解决方案,我将修改后的代码放在下面。
// Controller
@RestController
@Api(produces = "application/json", protocols = "https", tags = "Securities", description = "Securities information")
public class SecuritiesInfoController extends Controller {
@Autowired
private SecuritiesInfoManager _securitiesInfoManager = new SecuritiesInfoManager();
@RequestMapping(value = "/security", method = RequestMethod.GET)
public List<SecuritiesInfo> getAll(){
return _securitiesInfoManager.getAll();
}
}
//服务
public class SecuritiesInfoManager extends Manager {
@Autowired
public void setSecuritiesInfoDAOInterface(SecuritiesInfoDAOInterface _securitiesInfoDAOInterface) {
this._securitiesInfoDAOInterface = _securitiesInfoDAOInterface;
}
public List<SecuritiesInfo> getAll() {
return _securitiesInfoDAOInterface.getAll();
}
}
//DAO
public class SecuritiesInfoDAO extends DAO implements SecuritiesInfoDAOInterface {
private static String securitiesTable = "Securities";
@Override
public List<SecuritiesInfo> getAll() {
//Magic
}
}
//接口(interface)
public interface SecuritiesInfoDAOInterface {
@Cacheable(cacheNames = "SecuritiesInfo",cacheManager="cacheManager", keyGenerator="keyGenerator" )
List<SecuritiesInfo> getAll();
}
}
//缓存配置
@Configuration
@EnableCaching
public class CacheConfig extends CachingConfigurerSupport {
@Bean
public SecuritiesInfoManager myService() {
// configure and return a class having @Cacheable methods
return new SecuritiesInfoManager();
}
//rest same as before
}
//WebConfig
@Configuration
@ComponentScan(basePackages = {"package name"})
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
AntPathMatcher matcher = new AntPathMatcher();
matcher.setCaseSensitive(false);
configurer.setPathMatcher(matcher);
}
}
关于java - DAO 层中的@Cacheable 未被触发(Spring/Redis),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40687377/