Create AOP examples
- Use different types of advice - Use various types of pointcut expressions
This commit is contained in:
		
							parent
							
								
									c58922a8de
								
							
						
					
					
						commit
						175f119573
					
				| @ -0,0 +1,34 @@ | |||||||
|  | package org.baeldung.aop; | ||||||
|  | 
 | ||||||
|  | import org.aspectj.lang.JoinPoint; | ||||||
|  | import org.aspectj.lang.annotation.Aspect; | ||||||
|  | import org.aspectj.lang.annotation.Before; | ||||||
|  | import org.aspectj.lang.annotation.Pointcut; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | import java.text.SimpleDateFormat; | ||||||
|  | import java.util.Date; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | @Aspect | ||||||
|  | public class LoggingAspect { | ||||||
|  | 
 | ||||||
|  |     private static Logger logger = Logger.getLogger(LoggingAspect.class.getName()); | ||||||
|  | 
 | ||||||
|  |     private ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() { | ||||||
|  |         @Override | ||||||
|  |         protected SimpleDateFormat initialValue() { | ||||||
|  |             return new SimpleDateFormat("[yyyy-mm-dd hh:mm:ss:SSS]"); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     @Pointcut("@target(org.springframework.stereotype.Repository)") | ||||||
|  |     public void repositoryMethods() {} | ||||||
|  | 
 | ||||||
|  |     @Before("repositoryMethods()") | ||||||
|  |     public void logMethodCall(JoinPoint jp) throws Throwable { | ||||||
|  |         String methodName = jp.getSignature().getName(); | ||||||
|  |         logger.info(sdf.get().format(new Date()) + methodName); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -16,7 +16,7 @@ public class PerformanceAspect { | |||||||
|     private static Logger logger = Logger.getLogger(PerformanceAspect.class.getName()); |     private static Logger logger = Logger.getLogger(PerformanceAspect.class.getName()); | ||||||
| 
 | 
 | ||||||
|     @Pointcut("within(@org.springframework.stereotype.Repository *)") |     @Pointcut("within(@org.springframework.stereotype.Repository *)") | ||||||
|     public void repositoryClassMethods() {}; |     public void repositoryClassMethods() {} | ||||||
| 
 | 
 | ||||||
|     @Around("repositoryClassMethods()") |     @Around("repositoryClassMethods()") | ||||||
|     public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable { |     public Object measureMethodExecutionTime(ProceedingJoinPoint pjp) throws Throwable { | ||||||
|  | |||||||
| @ -0,0 +1,36 @@ | |||||||
|  | package org.baeldung.aop; | ||||||
|  | 
 | ||||||
|  | import org.aspectj.lang.JoinPoint; | ||||||
|  | import org.aspectj.lang.annotation.AfterReturning; | ||||||
|  | import org.aspectj.lang.annotation.Aspect; | ||||||
|  | import org.aspectj.lang.annotation.Pointcut; | ||||||
|  | import org.baeldung.events.FooCreationEvent; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.context.ApplicationEventPublisher; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | @Aspect | ||||||
|  | public class PublishingAspect { | ||||||
|  | 
 | ||||||
|  |     private ApplicationEventPublisher eventPublisher; | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     public void setEventPublisher(ApplicationEventPublisher eventPublisher) { | ||||||
|  |         this.eventPublisher = eventPublisher; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Pointcut("@target(org.springframework.stereotype.Repository)") | ||||||
|  |     public void repositoryMethods() {} | ||||||
|  | 
 | ||||||
|  |     @Pointcut("execution(* *..create*(Long,..))") | ||||||
|  |     public void firstLongParamMethods() {} | ||||||
|  | 
 | ||||||
|  |     @Pointcut("repositoryMethods() && firstLongParamMethods()") | ||||||
|  |     public void entityCreationMethods() {} | ||||||
|  | 
 | ||||||
|  |     @AfterReturning(value = "entityCreationMethods()", returning = "entity") | ||||||
|  |     public void logMethodCall(JoinPoint jp, Object entity) throws Throwable { | ||||||
|  |         eventPublisher.publishEvent(new FooCreationEvent(entity)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,10 +1,16 @@ | |||||||
| package org.baeldung.dao; | package org.baeldung.dao; | ||||||
| 
 | 
 | ||||||
|  | import org.baeldung.model.Foo; | ||||||
| import org.springframework.stereotype.Repository; | import org.springframework.stereotype.Repository; | ||||||
| 
 | 
 | ||||||
| @Repository | @Repository | ||||||
| public class FooDao { | public class FooDao { | ||||||
|  | 
 | ||||||
|     public String findById(Long id) { |     public String findById(Long id) { | ||||||
|         return "Bazz"; |         return "Bazz"; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public Foo create(Long id, String name) { | ||||||
|  |         return new Foo(id, name); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,10 @@ | |||||||
|  | package org.baeldung.events; | ||||||
|  | 
 | ||||||
|  | import org.springframework.context.ApplicationEvent; | ||||||
|  | 
 | ||||||
|  | public class FooCreationEvent extends ApplicationEvent { | ||||||
|  | 
 | ||||||
|  |     public FooCreationEvent(Object source) { | ||||||
|  |         super(source); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | package org.baeldung.events; | ||||||
|  | 
 | ||||||
|  | import org.springframework.context.ApplicationListener; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | 
 | ||||||
|  | @Component | ||||||
|  | public class FooCreationEventListener implements ApplicationListener<FooCreationEvent> { | ||||||
|  | 
 | ||||||
|  |     private static Logger logger = Logger.getLogger(FooCreationEventListener.class.getName()); | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void onApplicationEvent(FooCreationEvent event) { | ||||||
|  |         logger.info("Created foo instance: " + event.getSource().toString()); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										19
									
								
								spring-mvc-java/src/main/java/org/baeldung/model/Foo.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								spring-mvc-java/src/main/java/org/baeldung/model/Foo.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | package org.baeldung.model; | ||||||
|  | 
 | ||||||
|  | public class Foo { | ||||||
|  |     private Long id; | ||||||
|  |     private String name; | ||||||
|  | 
 | ||||||
|  |     public Foo(Long id, String name) { | ||||||
|  |         this.id = id; | ||||||
|  |         this.name = name; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String toString() { | ||||||
|  |         return "Foo{" + | ||||||
|  |                 "id=" + id + | ||||||
|  |                 ", name='" + name + '\'' + | ||||||
|  |                 '}'; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,19 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <beans xmlns="http://www.springframework.org/schema/beans" | ||||||
|  |        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |        xmlns:aop="http://www.springframework.org/schema/aop" | ||||||
|  |        xsi:schemaLocation="http://www.springframework.org/schema/beans | ||||||
|  |         http://www.springframework.org/schema/beans/spring-beans-4.2.xsd | ||||||
|  |         http://www.springframework.org/schema/aop | ||||||
|  |         http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> | ||||||
|  | 
 | ||||||
|  |     <bean id="perfomanceMeter" class="org.baeldung.aop.PerformanceAspect"/> | ||||||
|  |     <bean id="fooDao" class="org.baeldung.dao.FooDao"/> | ||||||
|  | 
 | ||||||
|  |     <aop:config> | ||||||
|  |         <aop:pointcut id="anyDaoMethod" expression="@target(org.springframework.stereotype.Repository)"/> | ||||||
|  |         <aop:aspect ref="perfomanceMeter"> | ||||||
|  |             <aop:around method="measureMethodExecutionTime" pointcut-ref="anyDaoMethod"/> | ||||||
|  |         </aop:aspect> | ||||||
|  |     </aop:config> | ||||||
|  | </beans> | ||||||
| @ -0,0 +1,67 @@ | |||||||
|  | package org.baeldung.aop; | ||||||
|  | 
 | ||||||
|  | import org.baeldung.config.TestConfig; | ||||||
|  | import org.baeldung.dao.FooDao; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.test.context.ContextConfiguration; | ||||||
|  | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||||
|  | import org.springframework.test.context.support.AnnotationConfigContextLoader; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.logging.Handler; | ||||||
|  | import java.util.logging.LogRecord; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  | 
 | ||||||
|  | import static org.hamcrest.Matchers.hasSize; | ||||||
|  | import static org.junit.Assert.assertThat; | ||||||
|  | import static org.junit.Assert.assertTrue; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringJUnit4ClassRunner.class) | ||||||
|  | @ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class) | ||||||
|  | public class AopLoggingTest { | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         logEventHandler = new Handler() { | ||||||
|  |             @Override | ||||||
|  |             public void publish(LogRecord record) { | ||||||
|  |                 messages.add(record.getMessage()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void flush() { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void close() throws SecurityException { | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         messages = new ArrayList<>(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private FooDao dao; | ||||||
|  | 
 | ||||||
|  |     private Handler logEventHandler; | ||||||
|  | 
 | ||||||
|  |     private List<String> messages; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenLoggingAspect_whenCallDaoMethod_thenBeforeAdviceIsCalled() { | ||||||
|  |         Logger logger = Logger.getLogger(LoggingAspect.class.getName()); | ||||||
|  |         logger.addHandler(logEventHandler); | ||||||
|  | 
 | ||||||
|  |         dao.findById(1L); | ||||||
|  |         assertThat(messages, hasSize(1)); | ||||||
|  | 
 | ||||||
|  |         String logMessage = messages.get(0); | ||||||
|  |         Pattern pattern = Pattern.compile("^\\[\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}:\\d{2}:\\d{2}:\\d{3}\\]findById$"); | ||||||
|  |         assertTrue(pattern.matcher(logMessage).matches()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,67 @@ | |||||||
|  | package org.baeldung.aop; | ||||||
|  | 
 | ||||||
|  | import org.baeldung.config.TestConfig; | ||||||
|  | import org.baeldung.dao.FooDao; | ||||||
|  | import org.baeldung.events.FooCreationEventListener; | ||||||
|  | import org.baeldung.model.Foo; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.test.context.ContextConfiguration; | ||||||
|  | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||||
|  | import org.springframework.test.context.support.AnnotationConfigContextLoader; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.logging.Handler; | ||||||
|  | import java.util.logging.LogRecord; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  | 
 | ||||||
|  | import static org.junit.Assert.assertTrue; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringJUnit4ClassRunner.class) | ||||||
|  | @ContextConfiguration(classes = {TestConfig.class}, loader = AnnotationConfigContextLoader.class) | ||||||
|  | public class AopPublishingTest { | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         logEventHandler = new Handler() { | ||||||
|  |             @Override | ||||||
|  |             public void publish(LogRecord record) { | ||||||
|  |                 messages.add(record.getMessage()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void flush() { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void close() throws SecurityException { | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         messages = new ArrayList<>(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private FooDao dao; | ||||||
|  | 
 | ||||||
|  |     private Handler logEventHandler; | ||||||
|  | 
 | ||||||
|  |     private List<String> messages; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenPublishingAspect_whenCallCreate_thenCreationEventIsPublished() { | ||||||
|  |         Logger logger = Logger.getLogger(FooCreationEventListener.class.getName()); | ||||||
|  |         logger.addHandler(logEventHandler); | ||||||
|  | 
 | ||||||
|  |         dao.create(1L, "Bar"); | ||||||
|  | 
 | ||||||
|  |         String logMessage = messages.get(0); | ||||||
|  |         Pattern pattern = Pattern.compile("Created foo instance: " + | ||||||
|  |                 Pattern.quote(new Foo(1L, "Bar").toString())); | ||||||
|  |         assertTrue(pattern.matcher(logMessage).matches()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,67 @@ | |||||||
|  | package org.baeldung.aop; | ||||||
|  | 
 | ||||||
|  | import org.baeldung.dao.FooDao; | ||||||
|  | import org.junit.Before; | ||||||
|  | import org.junit.Test; | ||||||
|  | import org.junit.runner.RunWith; | ||||||
|  | import org.springframework.beans.factory.annotation.Autowired; | ||||||
|  | import org.springframework.test.context.ContextConfiguration; | ||||||
|  | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | import java.util.logging.Handler; | ||||||
|  | import java.util.logging.LogRecord; | ||||||
|  | import java.util.logging.Logger; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  | 
 | ||||||
|  | import static org.hamcrest.CoreMatchers.notNullValue; | ||||||
|  | import static org.hamcrest.Matchers.hasSize; | ||||||
|  | import static org.junit.Assert.assertThat; | ||||||
|  | import static org.junit.Assert.assertTrue; | ||||||
|  | 
 | ||||||
|  | @RunWith(SpringJUnit4ClassRunner.class) | ||||||
|  | @ContextConfiguration("/org/baeldung/aop/beans.xml") | ||||||
|  | public class AopXmlConfigPerformanceTest { | ||||||
|  | 
 | ||||||
|  |     @Before | ||||||
|  |     public void setUp() { | ||||||
|  |         logEventHandler = new Handler() { | ||||||
|  |             @Override | ||||||
|  |             public void publish(LogRecord record) { | ||||||
|  |                 messages.add(record.getMessage()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void flush() { | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @Override | ||||||
|  |             public void close() throws SecurityException { | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         messages = new ArrayList<>(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Autowired | ||||||
|  |     private FooDao dao; | ||||||
|  | 
 | ||||||
|  |     private Handler logEventHandler; | ||||||
|  | 
 | ||||||
|  |     private List<String> messages; | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void givenPerformanceAspect_whenCallDaoMethod_thenPerformanceMeasurementAdviceIsCalled() { | ||||||
|  |         Logger logger = Logger.getLogger(PerformanceAspect.class.getName()); | ||||||
|  |         logger.addHandler(logEventHandler); | ||||||
|  | 
 | ||||||
|  |         final String entity = dao.findById(1L); | ||||||
|  |         assertThat(entity, notNullValue()); | ||||||
|  |         assertThat(messages, hasSize(1)); | ||||||
|  | 
 | ||||||
|  |         String logMessage = messages.get(0); | ||||||
|  |         Pattern pattern = Pattern.compile("Execution of findById took \\d+ ms"); | ||||||
|  |         assertTrue(pattern.matcher(logMessage).matches()); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration; | |||||||
| import org.springframework.context.annotation.EnableAspectJAutoProxy; | import org.springframework.context.annotation.EnableAspectJAutoProxy; | ||||||
| 
 | 
 | ||||||
| @Configuration | @Configuration | ||||||
| @ComponentScan(basePackages = {"org.baeldung.dao", "org.baeldung.aop"}) | @ComponentScan(basePackages = {"org.baeldung.dao", "org.baeldung.aop", "org.baeldung.events"}) | ||||||
| @EnableAspectJAutoProxy | @EnableAspectJAutoProxy | ||||||
| public class TestConfig { | public class TestConfig { | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user