Application of Spring AOP Notification
xml version
Create a new maven project
Project Structure Diagram
pom.xml file
<?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.spring</groupId> <artifactId>SpringAOP</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
Create a new advice class to configure notifications
package com.spring.advice; import org.aspectj.lang.ProceedingJoinPoint; public class MyAdvice { public void before(){ System.out.println("Before advice"); } public void afterReturning(){ System.out.println("Post notification"); } public void afterThrowing(){ System.out.println("Exception notification"); } public void after(){ System.out.println("Final notice"); } /** * Around Advice * @param pjp Obtain the information of the target object and its method parameters, etc. * @return */ public Object around(ProceedingJoinPoint pjp){ Object obj = null; try { System.out.println("Around Advice--Before advice"); //Get the parameters of the current execution method Object[] args = pjp.getArgs(); //Release method obj = pjp.proceed(args); System.out.println("Around Advice--Post notification"); }catch (Throwable t){ t.printStackTrace(); System.out.println("Around Advice--Exception notification"); }finally { System.out.println("Around Advice--Final notice"); } return obj; }
Create a service class
package com.spring.service; public interface Service { public void findAll(); public Integer save(); public Integer update(Integer i); }
Implementation class of service
package com.spring.service.impl; import com.spring.service.Service; public class ServiceImpl implements Service { @Override public void findAll() { //int i=1/0; System.out.println("query was successful"); } @Override public Integer save() { System.out.println("Save successfully"); return 1; } @Override public Integer update(Integer i) { System.out.println("Update success"); return 1; } }
Create a beans.xml file to configure entry points for notifications
<?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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--Deliver the target object to ioc container--> <bean id="userService" class="com.spring.service.impl.ServiceImpl"/> <!--Deliver the notification object to ioc container--> <bean id="myAdvice" class="com.spring.advice.MyAdvice"/> <!--To configure aop:It can be configured with multiple facets.--> <aop:config> <!--Pointcut expression--> <aop:pointcut id="pointcut" expression="execution(* com.spring.service.impl.*.*(..))"/> <!-- //A specific aspect configuration id Is the only identification of the current section ref Is to specify which notification to use for the current aspect --> <aop:aspect id="aspect" ref="myAdvice"> <!--Before advice--> <!--Notification class myAdvice Medium before Method in UserServiceImpl.findAll Execution before execution--> <aop:before method="before" pointcut-ref="pointcut"/> <!--Post notification--> <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/> <!--Exception notification--> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"/> <!--Final notice--> <aop:after method="after" pointcut-ref="pointcut"/> <!--Around Advice--> <!--<aop:around method="around" pointcut-ref="pointcut"/>--> </aop:aspect> </aop:config> </beans>
Test class
package com.spring.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; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:beans.xml") public class Test { @Autowired private com.spring.service.Service service; @org.junit.Test public void test() { service.findAll(); System.out.println(); } }
Test results:
Before advice query was successful Post notification Final notice
If you want to use surround notification, you need to annotate the pre-notification, post-notification, and final notification in beans.xml, and then open the annotation of surround notification.
Annotated edition
Project Structure Diagram
The pom.xml file is the same as the XML version
Class advice
package com.spring.advice; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class MyAdvice { @Pointcut("execution(* com.spring.service.impl.*.*(..))") public void pointcut(){}; @Before("pointcut()") public void before(){ System.out.println("Before advice"); } @AfterReturning("pointcut()") public void afterReturning(){ System.out.println("Post notification"); } @AfterThrowing("pointcut()") public void afterThrowing(){ System.out.println("Exception notification"); } @After("pointcut()") public void after(){ System.out.println("Final notice"); } /** * Around Advice * @param pjp Obtain the information of the target object and its method parameters, etc. * @return */ // @Around("execution(* com.spring.service.impl.*.*(..))") public Object around(ProceedingJoinPoint pjp){ Object obj = null; try { System.out.println("Before advice"); //Get the parameters of the current execution method Object[] args = pjp.getArgs(); //Release method obj = pjp.proceed(args); System.out.println("Post notification"); }catch (Throwable t){ t.printStackTrace(); System.out.println("Exception notification"); }finally { System.out.println("Final notice"); } return obj; } }
Class service
package com.spring.service; public interface Service { public void findAll(); public Integer save(); public Integer update(Integer i); }
package com.spring.service.impl; import com.spring.service.Service; @org.springframework.stereotype.Service public class ServiceImpl implements Service { @Override public void findAll() { //int i=1/0; System.out.println("query was successful"); } @Override public Integer save() { System.out.println("Save successfully"); return 1; } @Override public Integer update(Integer i) { System.out.println("Update success"); return 1; } }
Write a configuration class
package com.spring.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; @ComponentScan("com.spring") @EnableAspectJAutoProxy public class SpringConfig { }
Test class
package com.spring.test; import com.spring.config.SpringConfig; import com.spring.service.Service; 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 javax.annotation.Resource; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = SpringConfig.class) public class Test { @Resource private Service service; @Test public void test() { service.findAll(); System.out.println(); } }
Test results:
Before advice query was successful Final notice Post notification