spring Aop实战
1.五大通知注解
@Before 前置通知 @After 后置通知 @AfterReturning 返回通知 @AfterThrowable 异常通知 @Around 环绕通知
1.1 @AfterReturning对方法返回的数据进行处理
自定义注解(@ProcessMultiply相当于切入点)
@Retention ( RetentionPolicy. RUNTIME)
@Target ( { ElementType. METHOD} )
public @interface ProcessMultiply {
}
@Aspect
@Component
public class MultiplyAspect {
private static final Logger LOGGER = LoggerFactory. getLogger ( MultiplyAspect. class ) ;
private final MultiplyHandler multiplyHandler;
public MultiplyAspect ( MultiplyHandler multiplyHandler) {
this . multiplyHandler = multiplyHandler;
}
@AfterReturning ( value = "@annotation(自定义注解的完整路径)" , returning = "result" )
public Object afterReturning ( JoinPoint proceedingJoinPoint, Object result) throws Throwable {
return multiplyHandler. process ( result) ;
}
}
@Component
public class MultiplyHandler {
private static final Logger LOGGER = LoggerFactory. getLogger ( MultiplyHandler. class ) ;
private final MultiplyDBHandler multiplyDBHandler;
private final MultiplyCacheHandler multiplyCacheHandler;
public MultiplyHandler ( MultiplyDBHandler multiplyDBHandler, MultiplyCacheHandler multiplyCacheHandler) {
this . multiplyDBHandler = multiplyDBHandler;
this . multiplyCacheHandler = multiplyCacheHandler;
}
public Object process ( Object result) {
LOGGER. info ( "process method start" ) ;
if ( ObjectUtils. isEmpty ( result) ) {
return result;
}
result = multiplyDBHandler. processMultiplyFromDB ( result) ;
return result;
}
}
@Component
public class MultiplyDBHandler {
private static final Logger LOGGER = LoggerFactory. getLogger ( MultiplyDBHandler. class ) ;
private final IConditionsMulRepository conditionsRepository;
public MultiplyDBHandler ( IConditionsMulRepository conditionsRepository) {
this . conditionsRepository = conditionsRepository;
}
public Object processMultiplyFromDB ( Object result) {
if ( result instanceof Collection ) {
long startTime = System. currentTimeMillis ( ) ;
processCollection ( ( Collection< ? > ) result) ;
long endTime = System. currentTimeMillis ( ) ;
LOGGER. info ( "translate Mul Language Collection size:" + ( ( Collection< ? > ) result) . size ( ) + ",spend time:" + ( endTime - startTime) + "ms" ) ;
} else {
processObject ( result) ;
}
return result;
}
private void processCollection ( Collection< ? > collection) {
if ( CollectionUtils. isEmpty ( collection) ) {
return ;
}
Object o = collection. stream ( ) . findFirst ( ) . orElse ( null) ;
if ( collection instanceof Page ) {
o = ( ( Page< ? > ) collection) . getContent ( ) . stream ( ) . findFirst ( ) . orElse ( null) ;
}
if ( Objects. isNull ( o) ) {
return ;
}
List< Field> fields = FieldUtils. getFieldsListWithAnnotation ( o. getClass ( ) , MultiplyField. class ) ;
List< MultiplyVO> multiplyVOList = packagingMultiplyVOList ( fields, collection) ;
if ( CollectionUtils. isEmpty ( multiplyVOList) ) {
return ;
}
for ( MultiplyVO multiplyVO : multiplyVOList) {
collection. forEach ( x - > reflectToValue ( multiplyVO, x) ) ;
}
}
private void processObject ( Object object) {
List< Field> fields = FieldUtils. getFieldsListWithAnnotation ( object. getClass ( ) , MultiplyField. class ) ;
List< MultiplyVO> multiplyVOList = packagingMultiplyVOList ( fields, object) ;
if ( CollectionUtils. isEmpty ( multiplyVOList) ) {
return ;
}
for ( MultiplyVO multiplyVO : multiplyVOList) {
reflectToValue ( multiplyVO, object) ;
}
}
private List< MultiplyVO> packagingMultiplyVOList ( List< Field> fields, Object object) {
List< MultiplyVO> multiplyVOList = getMultiplyVO ( fields, object) ;
if ( CollectionUtils. isEmpty ( multiplyVOList) ) {
return multiplyVOList;
}
multiplyVOList. forEach ( mul - > mul. setTargetValueMap ( conditionsRepository. getValueMapByConditions ( mul. getIdentityKeyValueSet ( ) , mul. getTargetClass ( ) ,
mul. getTargetKey ( ) , mul. getTargetField ( ) ) ) ) ;
return multiplyVOList;
}
private List< MultiplyVO> getMultiplyVO ( List< Field> fields, Object result) {
List< MultiplyVO> multiplyVOList = Lists. newArrayList ( ) ;
if ( CollectionUtils. isEmpty ( fields) ) {
return multiplyVOList;
}
for ( Field field : fields) {
MultiplyVO multiplyVO = new MultiplyVO ( field, result) ;
multiplyVOList. add ( multiplyVO) ;
}
return multiplyVOList;
}
private void reflectToValue ( MultiplyVO multiplyVO, Object o) {
if ( MapUtils. isEmpty ( multiplyVO. getTargetValueMap ( ) ) ) {
return ;
}
try {
String typeName = o. getClass ( ) . getDeclaredField ( multiplyVO. getIdentityKey ( ) ) . getType ( ) . getSimpleName ( ) ;
String value = BeanUtils. getProperty ( o, multiplyVO. getIdentityKey ( ) ) ;
if ( Objects. isNull ( value) ) {
return ;
}
String name = "" ;
switch ( typeName) {
case "Long" :
name = String. valueOf ( multiplyVO. getTargetValueMap ( ) . get ( Long. valueOf ( value) ) ) ;
break ;
case "String" :
name = String. valueOf ( multiplyVO. getTargetValueMap ( ) . get ( value) ) ;
break ;
default :
LOGGER. error ( "No support identityKey class type" ) ;
break ;
}
BeanUtils. setProperty ( o, multiplyVO. getIdentityField ( ) , name) ;
} catch ( Exception e) {
LOGGER. error ( "reflectToValue method error" , e) ;
}
}
}
1.2 @Around通知处理excel导出
@Target ( ElementType. METHOD)
@Retention ( RetentionPolicy. RUNTIME)
@Documented
public @interface ExcelExport {
Class< ? > value ( ) default Object. class ;
Class< ? > [ ] groups ( ) default { } ;
String templateCode ( ) default "" ;
long maxDataCount ( ) default 0 L;
}
@Aspect
@Order ( 10 )
public class ExcelExportAop {
private static final Logger LOGGER = LoggerFactory. getLogger ( ExcelExportAop. class ) ;
private final ExportDataHelper exportDataHelper;
private final ExportColumnHelper exportColumnHelper;
public ExcelExportAop ( ExportDataHelper exportDataHelper, ExportColumnHelper exportColumnHelper) {
this . exportDataHelper = exportDataHelper;
this . exportColumnHelper = exportColumnHelper;
}
@Around ( value = "@annotation(excelExport)" )
public Object excelExport ( ProceedingJoinPoint joinPoint, ExcelExport excelExport) throws Throwable {
HttpServletResponse response = null;
ExportParam exportParam = null;
Object[ ] args = joinPoint. getArgs ( ) ;
for ( Object arg : args) {
if ( arg instanceof HttpServletResponse ) {
response = ( HttpServletResponse) arg;
} else if ( arg instanceof ExportParam ) {
exportParam = ( ExportParam) arg;
}
}
if ( exportParam == null || exportParam. getExportType ( ) == null || ! ExportType. match ( exportParam. getExportType ( ) ) ) {
return joinPoint. proceed ( ) ;
}
Assert. notNull ( response, "HttpServletResponse must not be null." ) ;
if ( ExportType. COLUMN. equals ( exportParam. getExportType ( ) ) ) {
ExportColumn exportColumn = exportColumnHelper. getExportColumn ( excelExport) ;
ResponseWriter. write ( response, exportColumn) ;
} else {
if ( StringUtils. isBlank ( excelExport. templateCode ( ) ) && CollectionUtils. isEmpty ( exportParam. getIds ( ) ) ) {
ExceptionResponse exceptionResponse = new ExceptionResponse ( "export.column.least-one" ) ;
LOGGER. warn ( exceptionResponse. getMessage ( ) ) ;
ResponseWriter. write ( response, exceptionResponse) ;
return null;
}
try {
doExportByType ( exportParam. getExportType ( ) , joinPoint, excelExport, response) ;
} catch ( CommonException e) {
LOGGER. warn ( "excel export error." , e) ;
ExceptionResponse exceptionResponse = new ExceptionResponse ( e. getCode ( ) ) ;
ResponseWriter. write ( response, exceptionResponse) ;
} catch ( Exception e) {
LOGGER. warn ( "excel export error." , e) ;
ExceptionResponse exceptionResponse = new ExceptionResponse ( "export.error" ) ;
exceptionResponse. setException ( e. getMessage ( ) ) ;
ResponseWriter. write ( response, exceptionResponse) ;
}
}
return null;
}
private void doExportByType ( ExportType type, ProceedingJoinPoint joinPoint, ExcelExport excelExport, HttpServletResponse response) throws Exception {
if ( ExportType. DATA. equals ( type) ) {
exportDataHelper. exportExcel ( joinPoint, excelExport, response) ;
} else if ( ExportType. TEMPLATE. equals ( type) ) {
exportDataHelper. exportTemplate ( joinPoint, excelExport, response) ;
}
}
}