
## 线程的使用方式
1、集成Thread
2、实现Runnable
3、实现Callable
4、创建线程池
5、@EnableAsync启动类 + @Async auditnews
@Async
## 作业
@Async失效的场景
## 分布式环境下生成唯一不重复id
1、UUID,32位字母数字组合。不适合做主键
2、时间戳。YYYYMMddHHmmssSSSRRRR,23位数字
3、雪花算法。19位的long型数据。
4、使用第三方,redis,mongodb,Zookeeper
## 自媒体异步审核文章
在wmnewsserviceImpl中添加代码
保存文章成功后,异步调用审核代码
自媒体异步审核文章
在wmnewsserviceImpl中最后一个if添加代码
wmNewsAuditService.注入
保存文章成功后,异步调用审核代码
if(!dto.getDraft()){
log.info("异步提交,审核文章");
threadpool wmNewsAuditService.auditWmNews(wmNews);
}
service
package com.heima.wemedia.service.impl;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.BeanHelper;
import com.heima.feignclient.client.ArticleFeign;
import com.heima.model.media.dtos.WmNewsResultDTO;
import com.heima.wemedia.entity.WmNews;
import com.heima.wemedia.service.WmNewsAuditService;
import com.heima.wemedia.service.WmNewsService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.swing.plaf.synth.SynthTextAreaUI;
@Slf4j
@Service
public class WmNewsAuditServiceImpl implements WmNewsAuditService {
@Lazy
@Autowired
private WmNewsService wmNewsService;
@Autowired
private ArticleFeign articleFeign;
@Override
@GlobalTransactional(rollbackFor = Exception.class)
@Async
怎么知道异步打印 log.info("开始审核文章");9003exec--->task1
public void auditWmNews(WmNews wmNews) {
log.info("开始审核文章");
if(wmNews.getStatus()!=1){
log.info("不是待审核状态,结束");
return ;
}
Integer wmNewsId = wmNews.getId();
没有时间为null
updateWmNewsStaus(wmNewsId,8,null,null);
if(wmNews.getPublishTime() != null &&
System.currentTimeMillis() < wmNews.getPublishTime().getTime()){
log.info("没有到发布时间,结束");
return ;
}
WmNewsResultDTO newsResultDTO = BeanHelper.copyProperties(wmNews, WmNewsResultDTO.class);
用 对象转换 自媒体都认识
try {
Long articleId = articleFeign.saveArticle(newsResultDTO);
updateWmNewsStaus(wmNewsId,9,null,articleId);
}catch (Exception e){
log.error("远程调用article保存文章,失败");
e.printStackTrace();
throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
}
}
private void updateWmNewsStaus(Integer wmNewsId, int status, String reason,Long articleId) {
WmNews wmNews = new WmNews();
wmNews.setId(wmNewsId);
wmNews.setStatus(status);
if(status == 2 || status==3) {
wmNews.setReason(reason);
}
if(articleId != null){
wmNews.setArticleId(articleId);
}
boolean b = wmNewsService.updateById(wmNews);
if(!b){
log.error("更新文章状态失败,wmNewsId={}",wmNewsId);
throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
}
}
}
article创建文章
ApArticle实体类添加注解
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
ApArticleContent实体类添加注解
@TableId(value = "article_id",type = IdType.INPUT)
@ApiModelProperty(value = "文章ID")
private Long articleId;
controller
package com.heima.article.controller;
import com.heima.article.service.ApArticleService;
import com.heima.article.service.impl.ApArticleServiceImpl;
import com.heima.model.media.dtos.WmNewsResultDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ArticleController {
@Autowired
private ApArticleService apArticleService;
@PostMapping("/api/v1/article/save")
public Long saveArticle(@RequestBody WmNewsResultDTO dto){
return apArticleService.saveArticle(dto);
}
}
``
`
```js
service
service
package com.heima.article.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.heima.article.entity.ApArticle;
import com.heima.article.entity.ApArticleContent;
import com.heima.article.entity.ApAuthor;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.ApArticleContentService;
import com.heima.article.service.ApArticleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.service.ApAuthorService;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.exception.LeadException;
import com.heima.common.util.BeanHelper;
import com.heima.model.media.dtos.WmNewsResultDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
@Slf4j
@Service
public class ApArticleServiceImpl extends ServiceImpl<ApArticleMapper, ApArticle> implements ApArticleService {
@Autowired
private ApArticleContentService contentService;
@Autowired
private ApAuthorService apAuthorService;
@Override
@Transactional(rollbackFor = Exception.class)
public Long saveArticle(WmNewsResultDTO dto) {
Integer wmNewsId = dto.getId();
LambdaQueryWrapper<ApArticle> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ApArticle::getWmNewsId,wmNewsId);
ApArticle article = getOne(queryWrapper);
if(article==null){
article = BeanHelper.copyProperties(dto,ApArticle.class);
article.setId(null);
Integer wmUserId = dto.getWmUserId();
ApAuthor apAuthor = apAuthorService.getByWmUserId(wmUserId);
if(apAuthor != null) {
article.setAuthorId(apAuthor.getId());
article.setAuthorName(apAuthor.getName());
}
没有初始值要设置
article.setLayout(dto.getType());
article.setFlag(0);
article.setLikes(0L);
article.setComments(0L);
article.setViews(0L);
article.setCollection(0L);
article.setCreatedTime(new Date());
article.setPublishTime(dto.getPublishTime()==null?new Date():dto.getPublishTime());
article.setIsComment(true);
article.setIsForward(true);
article.setIsDelete(false);
article.setIsDown(false);
article.setWmNewsId(wmNewsId);
boolean b = save(article);
if(!b){
log.error("新增文章失败,wmNewsId={}",wmNewsId);
throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
}
}else{
article.setTitle(dto.getTitle());
article.setChannelId(dto.getChannelId());
article.setChannelName(dto.getChannelName());
article.setLabels(dto.getLabels());
article.setImages(dto.getImages());
article.setLayout(dto.getType());
article.setPublishTime(dto.getPublishTime()==null?new Date():dto.getPublishTime());
boolean b = updateById(article);
if(!b){
log.error("修改文章失败,articleId={}",article.getId());
throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
}
}
Long articleId = article.getId();
大字段的id
ApArticleContent apArticleContent = new ApArticleContent();
apArticleContent.setArticleId(articleId);
apArticleContent.setContent(dto.getContent());
boolean b = contentService.saveOrUpdate(apArticleContent);
if(!b){
log.error("新增/修改文章内容失败,articleId={}",articleId);
throw new LeadException(AppHttpCodeEnum.SERVER_ERROR);
}
return articleId;
}
}
在ArticleFeign接口中添加方法
@PostMapping("/api/v1/article/save")
Long saveArticle(@RequestBody WmNewsResultDTO dto);
自媒体服务weeadia添加feign依赖
<dependency>
<groupId>com.heima</groupId>
<artifactId>heima-leadnews-feign-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
自媒体启动类添加注解
@EnableFeignClients(basePackages = {"com.heima.feignclient.client"})
## 业务总结
### 自动审核
1、修改自媒体文章的状态
2、调用第三方接口,审核文章的内容和图片
3、远程调用article服务,创建文章和内容
mybaitsplus自动生成@
ApArticle实体类添加注解
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
技术点
1、异步调用的方式,@EnableAsync + @Async
2、生成分布式环境唯一不重复id的方式,雪花算法
3、MybatisPlus实体类标记主键,需要加注解@TableId
4、审核发布业务跨服务,需要是分布式事务
