@Transactional对于默认(package-private)级别的方法,会导致注入为null

文章讲述了在将项目从SpringBoot1.x升级到2.3.x时,由于在包内使用了`@Transactional`导致`DAO`类在某些非公开方法中无法正常注入的问题,解决方法是将这些方法改为`public`访问级别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目从springboot1.x升级到2.3.x时,发现调用方法时注入的dao类为空。经过长时间排查发现是@Transactional引起。以前一直的思路是只要@Transactional注释的方法为public就可以正常注入,但发现如果是同包下package-private级别的方法调用,也会导致注入为空。

下面代码是UserService中调用了menuService.listMenus()方法

UserService

public List<ProductDto> genProductDtoList(String roleTypeCode) {
        List<ProductEntity> productList = productService.listAllProducts();
        
        List<MenuDto> menuDtoList = menuService.listMenus(productCodeList, roleTypeCode);
       // 非关键代码省略....
     return ...
}

MenuService:

 List<MenuDto> listMenus(List<String> productCodeList, String roleTypeCode) {
        List<MenuEntity> leafMenus = menuDao.listMenus(productCodeList, roleTypeCode);
        if (leafMenus.isEmpty()) {
            return Lists.newArrayList();
        }
        Set<String> parentMenuCodes = leafMenus.stream().map(MenuEntity::getParentCode).collect(Collectors.toSet());
        List<MenuEntity> parentMenu = menuDao.listMenus(parentMenuCodes);
        List<MenuEntity> menus = Collections.concat(leafMenus, parentMenu);
        return menus.stream().map(MenuDto::new).collect(Collectors.toList());
    }

@Transactional(rollbackFor = Exception.class)
public void saveRelationsOfMenuAndRoleType(String typeCode, List<String> menuCodes) {
        menuDao.deleteRelationsByRoleType(typeCode);

        List<MenuEntity> menus = menuDao.listLeafMenus(menuCodes);
        if (menus.isEmpty() && !Objects.equals(typeCode,VISITOR)) {
            LOGGER.info("至少选择一个菜单!参数:{}", menuCodes);
            throw new DataException("至少选择一个菜单!");
        }
        // 省略代码 --------
    }

在MenuService中有其他的方法使用了@Transactional进行事务管理,会导致listMenus中的menuDao注入为null.原因就是listMenus方法未定义访问权限,默认是package-private。当把该方法改成public时,则能正常注入:

public List<MenuDto> listMenus(List<String> productCodeList, String roleTypeCode) {
        List<MenuEntity> leafMenus = menuDao.listMenus(productCodeList, roleTypeCode);
        if (leafMenus.isEmpty()) {
            return Lists.newArrayList();
        }
        Set<String> parentMenuCodes = leafMenus.stream().map(MenuEntity::getParentCode).collect(Collectors.toSet());
        List<MenuEntity> parentMenu = menuDao.listMenus(parentMenuCodes);
        List<MenuEntity> menus = Collections.concat(leafMenus, parentMenu);
        return menus.stream().map(MenuDto::new).collect(Collectors.toList());
    }

具体的源码后续分析,先用该方法解决业务报错问题处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值