@(工作笔记)

shiro-record

Alt text

[TOC]


Spring与Shiro加入DefaultAdvisorAutoProxyCreator后引起事务失效问题

/**
* Shiro注解
 * DefaultAdvisorAutoProxyCreator和AuthorizationAttributeSourceAdvisor。
 * 用了spring mvc的话就需要把这两个bean定义写在相应的springmvc-servlet.xml文件中
 */
@Bean
@DependsOn(value = "lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator creator  = new DefaultAdvisorAutoProxyCreator();
    /**
     * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。
     * 在@Controller注解的类的方法中加入@RequiresRole注解,会导致该方法无法映射请求,导致返回404。 加入这项配置能解决这个bug
     */
    creator.setUsePrefix(false);
    creator.setProxyTargetClass(true);
    return creator ;
}
@Autowired
@Bean(name = "authorizationAttributeSourceAdvisor")
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
            = new AuthorizationAttributeSourceAdvisor();
    authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    return authorizationAttributeSourceAdvisor;
}

由于ShiroFilterFactoryBean实现了FactoryBean接口,所以它会提前被初始化。又因为SecurityManager,SecurityManager依赖于Realm实现类、Realm实现类又依赖于UserService,所以引发所有相关的bean提前初始化,导致UserService并没有被事务AOP包裹着. 所以就出现了事务无效的问题.

解决方案

​ 在Realm中Service声明上加入@Lazy注解,延迟Realm实现中Service对象的初始化时间,这样就可以保证Service实际初始化的时候会被BeanPostProcessor拦截,创建具有事务功能的代理对象。

public final class AccountRealm extends AuthorizingRealm {
  private final static Logger logger = LogManager.getLogger(AccountRealm.class);

  @Autowired
  @Lazy
  private UserService userService;

  @Autowired
  @Lazy
  private ConfigService configService;

results matching ""

    No results matching ""