Background:

$\color{purple}{start date, start date, endDate

As a time range,}
\color{purple}{$$\color{purple}{$$\color{purple}{$$\color{purple}{$

Direct solution:

Date beginDate=param.getBeginDate(); Date endDate=param.getEndDate(); if ((beginDate ! = null && endDate ! = null) && beginDate.equals(endDate)) {// If the start and end times passed are the same, the end time plus one day c.setTime(beginDate); c.add(Calendar.DAY_OF_MONTH, 1); Date endTime = c.getTime(); endDateMap.get(arg.getClass()).set(arg, endTime); }Copy the code


But then you have to add this code to each query time range query method, which is very neat, \color{red}{if this is the case, you will need to add this code to the query method.}


Therefore, consider implementing this input parameter modification using non-intrusive annotations to the method body Color {red}{so consider using non-intrusive annotations to implement this input parameter modification}

Custom annotations +AOP:

First of all, make sure it’s in the project

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Copy the code

Custom annotations are then used to annotate the time-range query method

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeSpanCheck {

    //String beginDateFieldName();

    //String endDateFieldName();
}
Copy the code

I wanted to manually define beginDate and endDate field names, but I think that’s not a good idea. If you change the name of the field, you might get an error because you didn’t change it together. Since we’ve already used annotations to mark it, let’s use it again

Now, @documented // Note that @target is different, @Target(elementType. FIELD) @Retention(RetentionPolicy.runtime) Public @Interface BeginDate {} @documented @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface EndDate { }Copy the code

Once the annotation is defined, we add it to the corresponding method and field, and then it can be retrieved using reflection

Next, you can write the AOP class, which is directly on the code + comments

@Component @Aspect @Slf4j public class TimeSpanCheckAop { private Calendar c = Calendar.getInstance(); Private Map<Class, Field> beginDateMap = new HashMap<>(); private Map<Class, Field> endDateMap = new HashMap<>(); Pointcut("execution(* XXX.xxx.service.impl.. ") @pointcut ("execution(* xxx.xxx.service. * (..) ) && @annotation(xxx.xxx.service.aop.TimeSpanCheck)") public void pointCut() { } /** * If the method has an @timespanCheck annotation and beginDate is the same as EndDate, */ @around ("pointCut()") public Object TimeSpanCheck(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); TimeSpanCheck timeSpanCheck = method.getAnnotation(TimeSpanCheck.class); if (timeSpanCheck == null) { return true; } Object arg = args[0]; If (beginDatemap.get (arg.getClass()) == null && endDatemap.get (arg.getClass()) == null) { Find the Field marked @beginDate @endDate and store it in the cache map for (Field Field: arg.getClass().getDeclaredFields()) { BeginDate beginDate = field.getAnnotation(BeginDate.class); EndDate endDate = field.getAnnotation(EndDate.class); if (beginDate ! = null) { field.setAccessible(true); beginDateMap.put(arg.getClass(), field); } if (endDate ! = null) { field.setAccessible(true); endDateMap.put(arg.getClass(), field); Field beginDateField = beginDatemap.get (arg.getClass()); Field endDateField = endDateMap.get(arg.getClass()); if (beginDateField ! = null && endDateField ! = null) { Date beginDate = (Date) beginDateField.get(arg); Date endDate = (Date) endDateField.get(arg); if ((beginDate ! = null && endDate ! = null) && beginDate.equals(endDate)) {// If the start and end times passed are the same, the end time plus one day c.setTime(beginDate); c.add(Calendar.DAY_OF_MONTH, 1); Date endTime = c.getTime(); endDateMap.get(arg.getClass()).set(arg, endTime); Return joinPoint.proceed(args); }}Copy the code

Validation:


As you can see, after executing the method e n d D a t e Turned out to be b e g i n D a t e + 1 Oh, my God, that’s what we wanted \color{blue}{you can see that the endDate is beginDate + 1 day after executing the method.