如何在VO或者Entity类中调用springboot中的依赖注入?

如何在VO或者Entity类中调用springboot中的依赖注入?
情况是这样的,我有个PostVO类,其中有个catids属性需要通过另一个属性catid递归得到。我把方法写到了service的实现类(CatServiceImpl)里,然后在PostVO里调用。结果出问题了:CatServiceImpl必须交给springboot的ioc容器管理才行,不然mybatis-plus就没法用,这就意味着不能new,只能在PostVO中注入CatServiceImpl,这导致了报错,无法把PostVO封装成json(可能是因为其注入了CatService的实现类的原因),报错如下:

2024-06-08T12:25:05.100+08:00  WARN 4712 --- [blog] [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Type kotlin.reflect.KProperty1 not present]

PostVO.java代码如下:

// 文章展示类
@Data
@Component
public class PostVO {
    @Autowired
    private ICatService catService;

    private Integer postid;
    // 标题
    private String title;
    // 分类id
    private Integer catid;
    // 级联分类ids(为了兼容element-plus的Cascader组件)
    private Integer[] catids;
    // 内容
    private String content;
    private String thumb;
    private int posttime;
    private int updatetime;
    private short status;

    public void setCatid(Integer catid){
        this.catid = catid;

        // 获取id集合
        List<Integer> parentIds = catService.getParentIds(catid);
        // 反转结果集
        Collections.reverse(parentIds);
        // 将结果以数组形式付给VO的catids
        this.catids = parentIds.toArray(new Integer[0]);
    }
}

PostsController.java中相关代码如下:

/**
     * 根据id返回文章(未作权限处理)
     * 
     * @param id
     * @return
     */
    @GetMapping("/{postid}")
    public Result<PostVO> view(@PathVariable Integer postid) {
        Post post = postService.getById(postid);

        if (post != null) {
            // PostVO postVO = new PostVO();
            BeanUtils.copyProperties(post, postVO);
            System.out.println(postVO);
            // // 获取id集合
            // List<Integer> parentIds = catService.getParentIds(post.getCatid());
            // // 反转结果集
            // Collections.reverse(parentIds);
            // // 将结果以数组形式付给VO的catids
            // postVO.setCatids(parentIds.toArray(new Integer[0]));

            return Result.success(postVO);
        } else {
            return Result.fail(ResultCodeEnum.NOT_FOUND);
        }
    }

打印结果如下:

PostVO(catService=com.test.blog.service.impl.CatServiceImpl@52f90432, postid=22, title=我是标题哈哈哈, catid=11, catids=[2, 6, 11], content=我是内容啦啦啦啦啦啦啦啦啦, thumb=, posttime=0, updatetime=0, status=1)

之前我是把赋值放到controller里的,但是每次返回PostVO的时候都要写一遍,就想放到PostVO里,结果就出现了上面的问题。请大佬们解惑,我这种做法不对吗?不应该写到实体类中那应该写哪?

阅读 779
2 个回答

应该放在 postService 中实现。

补充下解决方案:用springboot的上下文容器的getBean方法来加载service。

①在启动类中获取上下文容器:
BlogApplication.java

@SpringBootApplication
public class BlogApplication {

    //在启动类运行时获取spring容器对象
    public static ConfigurableApplicationContext context;

    public static void main(String[] args) {
        context = SpringApplication.run(BlogApplication.class, args);
    }

}

②用上下文容器的getBean方法注入依赖
PostVO.java的实现代码如下:

public void setCatid(Integer catid){
        this.catid = catid;
        // 用上下文容器的getBean方法注入依赖
        ICatService catService = BlogApplication.context.getBean(ICatService.class);
        // 获取id集合
        List<Integer> parentIds = catService.getParentIds(catid);
        // 反转结果集
        Collections.reverse(parentIds);
        // 将结果以数组形式付给VO的catids
        this.catids = parentIds.toArray(new Integer[0]);
    }

方案二:感谢 @扬帆启航 提醒,在PostService里封装一个返回VO的通用方法:
PostServiceImpl.java 代码如下

@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements IPostService {

    @Lazy // 防止循环引用
    @Autowired
    private ICatService catService;

    @Override
    public PostVO getVO(Post post) {
        PostVO postVO = new PostVO();
        BeanUtils.copyProperties(post, postVO);
        // 获取id集合
        List<Integer> parentIds = catService.getParentIds(post.getCatid());
        // 反转结果集
        Collections.reverse(parentIds);
        // 将结果以数组形式付给VO的catids
        postVO.setCatids(parentIds.toArray(new Integer[0]));
        return postVO;
    }
}

PostsController.java

/**
     * 根据id返回文章(未作权限处理)
     * 
     * @param id
     * @return
     */
    @GetMapping("/{postid}")
    public Result<PostVO> view(@PathVariable Integer postid) {
        Post post = postService.getById(postid);

        if (post != null) {
            return Result.success(postService.getVO(post));
        } else {
            return Result.fail(ResultCodeEnum.NOT_FOUND);
        }
    }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏