Example - Code Logging
@Service public class MyService { public void method1(List<String> list) { list.add("method1"); System.out.println("MyService method1 list.size=" + list.size()); } @AspectAnnotation public void method2() { System.out.println("MyService method2"); } public boolean check() { System.out.println("MyService check"); return true; } }
@Aspect @Component public class MyAspect { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Pointcut("execution(public * com.example.demoAspects.MyService.*(..))") public void callAtMyServicePublic() { } @Before("callAtMyServicePublic()") public void beforeCallAtMethod1(JoinPoint jp) { String args = Arrays.stream(jp.getArgs()) .map(a -> a.toString()) .collect(Collectors.joining(",")); logger.info("before " + jp.toString() + ", args=[" + args + "]"); } @After("callAtMyServicePublic()") public void afterCallAt(JoinPoint jp) { logger.info("after " + jp.toString()); } }
@RunWith(SpringRunner.class) @SpringBootTest public class DemoAspectsApplicationTests { @Autowired private MyService service; @Test public void testLoggable() { List<String> list = new ArrayList(); list.add("test"); service.method1(list); service.method2(); Assert.assertTrue(service.check()); } }
@Aspect
class MyAspect ...
@Pointcut("execution(public * com.example.demoAspects.MyService.*(..))") public void callAtMyServicePublic() { }
Some examples of Pointcut and Advice are:
@Pointcut("@annotation(AspectAnnotation)") public void callAtMyServiceAnnotation() { }
@Before("callAtMyServiceAnnotation()") public void beforeCallAt() { }
@Pointcut("execution(* com.example.demoAspects.MyService.method1(..)) && args(list,..))") public void callAtMyServiceMethod1(List<String> list) { }
@Before("callAtMyServiceMethod1(list)") public void beforeCallAtMethod1(List<String> list) { }
@Pointcut("execution(* com.example.demoAspects.MyService.check())") public void callAtMyServiceAfterReturning() { }
@AfterReturning(pointcut="callAtMyServiceAfterReturning()", returning="retVal") public void afterReturningCallAt(boolean retVal) { }
Example of checking the rights to the Around type Advice, via annotation
@Retention(RUNTIME) @Target(METHOD) public @interface SecurityAnnotation { } // @Aspect @Component public class MyAspect { @Pointcut("@annotation(SecurityAnnotation) && args(user,..)") public void callAtMyServiceSecurityAnnotation(User user) { } @Around("callAtMyServiceSecurityAnnotation(user)") public Object aroundCallAt(ProceedingJoinPoint pjp, User user) { Object retVal = null; if (securityService.checkRight(user)) { retVal = pjp.proceed(); } return retVal; }
@Service public class MyService { @SecurityAnnotation public Balance getAccountBalance(User user) { // ... } @SecurityAnnotation public List<Transaction> getAccountTransactions(User user, Date date) { // ... } }
balance = myService.getAccountBalance(user); if (balance == null) { accessDenied(user); } else { displayBalance(balance); }
An example of profiling the same service using the Around type Advice
@Aspect @Component public class MyAspect { @Pointcut("execution(public * com.example.demoAspects.MyService.*(..))") public void callAtMyServicePublic() { } @Around("callAtMyServicePublic()") public Object aroundCallAt(ProceedingJoinPoint call) throws Throwable { StopWatch clock = new StopWatch(call.toString()); try { clock.start(call.toShortString()); return call.proceed(); } finally { clock.stop(); System.out.println(clock.prettyPrint()); } } }
Example use in UI forms
public class EditForm extends Form { @Override public void init(Form form) { formHelper.updateVisibility(form, settingsService.isVisible(COMP_NAME)); formHelper.updateVisibility(form, settingsService.isVisible(COMP_LAST_NAME)); formHelper.updateVisibility(form, settingsService.isVisible(COMP_BIRTH_DATE)); // ... }
@Aspect public class MyAspect { @Pointcut("execution(* com.example.demoAspects.EditForm.init() && args(form,..))") public void callAtInit(Form form) { } // ... @Around("callAtInit(form)") public Object aroundCallAt(ProceedingJoinPoint pjp, Form form) { formHelper.updateVisibility(form, settingsService.isVisible(COMP_NAME)); formHelper.updateVisibility(form, settingsService.isVisible(COMP_LAST_NAME)); formHelper.updateVisibility(form, settingsService.isVisible(COMP_BIRTH_DATE)); Object retVal = pjp.proceed(); return retVal; }
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>demoAspects</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demoAspects</name> <description>Demo project for Spring Boot Aspects</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Source: https://habr.com/ru/post/428548/
All Articles