Define an annotation that can be applied to methods and classes. If it is applied to a class, the annotation simply cascades and applies to all methods in the class.
package com.perfectcomputersolutions.pos.annotation;
import org.springframework.stereotype.Component;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Component
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NoNullArgs {
}
Then create a class with an advice (method to apply) to a series of point cuts (locations to apply the actual advice). Note. This is an example implemented in Groovy that merely checks that all arguments are not null. However, you can change the body of the method to do whatever you want. Once you have the args
array, those are the values that you can cast to the the expected type.
package com.perfectcomputersolutions.pos.aspect
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.reflect.CodeSignature
import org.springframework.core.annotation.Order
import org.springframework.stereotype.Component
@Aspect
@Order(0)
@Component
class NoNullArgsAspect {
// Use this if writing in Java.
// omitting the getMetaClass call is only for Groovy
// @Before(
// value = "@within(com.perfectcomputersolutions.pos.annotation.NoNullArgs) || @annotation(com.perfectcomputersolutions.pos.annotation.NoNullArgs)"
// )
@Before(
value = "!execution(* *.getMetaClass(..)) && @within(com.perfectcomputersolutions.pos.annotation.NoNullArgs) || @annotation(com.perfectcomputersolutions.pos.annotation.NoNullArgs)"
)
void requireNotNull(JoinPoint jp) {
def method = (CodeSignature) jp.signature
def types = method.parameterTypes
def names = method.parameterNames
def args = jp.args
for (int i = 0; i < types.length; i++)
Objects.requireNonNull(args[i], "Parameter ${names[i]} must not be null" as String)
}
}