Merge aspectj -> spring-aop (#1737)
This commit is contained in:
committed by
GitHub
parent
17ff6e50f4
commit
722ce8fba4
@@ -1,3 +1,5 @@
|
||||
### Relevant articles
|
||||
|
||||
- [Implementing a Custom Spring AOP Annotation](http://www.baeldung.com/spring-aop-annotation)
|
||||
- [Intro to AspectJ](http://www.baeldung.com/aspectj)
|
||||
- [Spring Performance Logging](http://www.baeldung.com/spring-performance-logging)
|
||||
13
spring-aop/src/main/java/org/baeldung/aspectj/Account.java
Normal file
13
spring-aop/src/main/java/org/baeldung/aspectj/Account.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
public class Account {
|
||||
int balance = 20;
|
||||
|
||||
public boolean withdraw(int amount) {
|
||||
if (balance < amount) {
|
||||
return false;
|
||||
}
|
||||
balance = balance - amount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public aspect AccountAspect {
|
||||
private static final Logger logger = LoggerFactory.getLogger(AccountAspect.class);
|
||||
final int MIN_BALANCE = 10;
|
||||
|
||||
pointcut callWithDraw(int amount, Account account):
|
||||
call(boolean Account.withdraw(int)) && args(amount) && target(account);
|
||||
|
||||
before(int amount, Account account) : callWithDraw(amount, account) {
|
||||
logger.info(" Balance before withdrawal: {}", account.balance);
|
||||
logger.info(" Withdraw ammout: {}", amount);
|
||||
}
|
||||
|
||||
boolean around(int amount, Account account) : callWithDraw(amount, account) {
|
||||
if (account.balance < amount) {
|
||||
logger.info("Withdrawal Rejected!");
|
||||
return false;
|
||||
}
|
||||
return proceed(amount, account);
|
||||
}
|
||||
|
||||
after(int amount, Account balance) : callWithDraw(amount, balance) {
|
||||
logger.info("Balance after withdrawal : {}", balance.balance);
|
||||
}
|
||||
}
|
||||
12
spring-aop/src/main/java/org/baeldung/aspectj/Secured.java
Normal file
12
spring-aop/src/main/java/org/baeldung/aspectj/Secured.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Secured {
|
||||
public boolean isLocked() default false;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class SecuredMethod {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SecuredMethod.class);
|
||||
|
||||
@Secured(isLocked = true)
|
||||
public void lockedMethod() throws Exception {
|
||||
logger.info("lockedMethod");
|
||||
}
|
||||
|
||||
@Secured(isLocked = false)
|
||||
public void unlockedMethod() {
|
||||
logger.info("unlockedMethod");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
SecuredMethod sv = new SecuredMethod();
|
||||
sv.lockedMethod();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
import org.aspectj.lang.ProceedingJoinPoint;
|
||||
import org.aspectj.lang.annotation.Around;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@Aspect
|
||||
public class SecuredMethodAspect {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SecuredMethodAspect.class);
|
||||
|
||||
@Pointcut("@annotation(secured)")
|
||||
public void callAt(Secured secured) {
|
||||
}
|
||||
|
||||
@Around("callAt(secured)")
|
||||
public Object around(ProceedingJoinPoint pjp, Secured secured) throws Throwable {
|
||||
if (secured.isLocked()) {
|
||||
logger.info(pjp.getSignature().toLongString() + " is locked");
|
||||
return null;
|
||||
} else {
|
||||
return pjp.proceed();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package org.baeldung.performancemonitor;
|
||||
|
||||
import org.aspectj.lang.annotation.Pointcut;
|
||||
import org.springframework.aop.Advisor;
|
||||
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
||||
import org.springframework.aop.interceptor.PerformanceMonitorInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy
|
||||
public class AopConfiguration {
|
||||
|
||||
@Pointcut("execution(public String com.baeldung.performancemonitor.PersonService.getFullName(..))")
|
||||
public void monitor() { }
|
||||
|
||||
@Pointcut("execution(public int com.baeldung.performancemonitor.PersonService.getAge(..))")
|
||||
public void myMonitor() { }
|
||||
|
||||
@Bean
|
||||
public PerformanceMonitorInterceptor performanceMonitorInterceptor() {
|
||||
return new PerformanceMonitorInterceptor(true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Advisor performanceMonitorAdvisor() {
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.monitor()");
|
||||
return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Person person(){
|
||||
return new Person("John","Smith", LocalDate.of(1980, Month.JANUARY, 12));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PersonService personService(){
|
||||
return new PersonService();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MyPerformanceMonitorInterceptor myPerformanceMonitorInterceptor() {
|
||||
return new MyPerformanceMonitorInterceptor(true);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Advisor myPerformanceMonitorAdvisor() {
|
||||
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
||||
pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.myMonitor()");
|
||||
return new DefaultPointcutAdvisor(pointcut, myPerformanceMonitorInterceptor());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.baeldung.performancemonitor;
|
||||
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.springframework.aop.interceptor.AbstractMonitoringInterceptor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class MyPerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {
|
||||
|
||||
public MyPerformanceMonitorInterceptor() {
|
||||
}
|
||||
|
||||
public MyPerformanceMonitorInterceptor(boolean useDynamicLogger) {
|
||||
setUseDynamicLogger(useDynamicLogger);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object invokeUnderTrace(MethodInvocation invocation, Log log) throws Throwable {
|
||||
|
||||
String name = createInvocationTraceName(invocation);
|
||||
long start = System.currentTimeMillis();
|
||||
log.info("Method "+name+" execution started at:"+new Date());
|
||||
try {
|
||||
return invocation.proceed();
|
||||
}
|
||||
finally {
|
||||
long end = System.currentTimeMillis();
|
||||
long time = end - start;
|
||||
log.info("Method "+name+" execution lasted:"+time+" ms");
|
||||
log.info("Method "+name+" execution ended at:"+new Date());
|
||||
|
||||
if (time > 10){
|
||||
log.warn("Method execution longer than 10 ms!");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.baeldung.performancemonitor;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
public class PerfomanceApp {
|
||||
public static void main(String[] args) {
|
||||
|
||||
ApplicationContext context = new AnnotationConfigApplicationContext(AopConfiguration.class);
|
||||
Person person = (Person) context.getBean("person");
|
||||
PersonService personService = (PersonService) context.getBean("personService");
|
||||
|
||||
System.out.println("Name is:"+personService.getFullName(person));
|
||||
System.out.println("Age is:"+personService.getAge(person));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.baeldung.performancemonitor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class Person {
|
||||
private String lastName;
|
||||
private String firstName;
|
||||
private LocalDate dateOfBirth;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String firstName, String lastName, LocalDate dateOfBirth) {
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public LocalDate getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(LocalDate dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.baeldung.performancemonitor;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Period;
|
||||
|
||||
public class PersonService {
|
||||
|
||||
public String getFullName(Person person){
|
||||
return person.getLastName()+" "+person.getFirstName();
|
||||
}
|
||||
|
||||
public int getAge(Person person){
|
||||
Period p = Period.between(person.getDateOfBirth(), LocalDate.now());
|
||||
return p.getYears();
|
||||
}
|
||||
|
||||
}
|
||||
8
spring-aop/src/main/resources/META-INF/aop.xml
Normal file
8
spring-aop/src/main/resources/META-INF/aop.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<aspectj>
|
||||
<aspects>
|
||||
<aspect name="org.baeldung.aspectj.SecuredMethodAspect"/>
|
||||
<weaver options="-verbose -showWeaveInfo">
|
||||
<include within="com.baeldung.aspectj.*"/>
|
||||
</weaver>
|
||||
</aspects>
|
||||
</aspectj>
|
||||
19
spring-aop/src/main/resources/logback.xml
Normal file
19
spring-aop/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>web - %date [%thread] %-5level %logger{36} - %message%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN" />
|
||||
<logger name="org.springframework.transaction" level="WARN" />
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class AccountTest {
|
||||
private Account account;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
account = new Account();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBalance20AndMinBalance10_whenWithdraw5_thenSuccess() {
|
||||
assertTrue(account.withdraw(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenBalance20AndMinBalance10_whenWithdraw100_thenFail() {
|
||||
assertFalse(account.withdraw(100));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.baeldung.aspectj;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class SecuredMethodTest {
|
||||
@Test
|
||||
public void testMethod() throws Exception {
|
||||
SecuredMethod service = new SecuredMethod();
|
||||
service.unlockedMethod();
|
||||
service.lockedMethod();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user