一、pom.xml
<?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>org.example</groupId> <artifactId>A02spring</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!--https://mvnrepository.com/artifact/org.springframework/spring-context--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.8.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
二、spring的xml配置文件
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--要被增强的类--> <bean id="sourceMethod" class="com.wuxi.services.impl.StudentServiceImpl"></bean> <!--增强的功能所在的类--> <bean id="adviceMethod" class="com.wuxi.utils.LoggerService"></bean> <!-- 切入点表达式 全通配符写法:* *..*.*(..) 修饰符可省略,*既作为通配符,也作为占位符,..意味多级包或多个参数 通知类型(增强功能的方式) 前置通知(aop:before):在切入点之前运行 后置通知(aop:after-returning):在切入点正常运行之后运行 异常通知(aop:after-throwing):切入点运行发生异常时运行 最终通知(aop:after):不管切入点有没有发生异常都会执行 环绕通知(aop:around):相当于前置通知+后置通知+异常通知+最终通知 --> <aop:config> <aop:pointcut id="pt" expression="execution(public void com.wuxi.services.impl.StudentServiceImpl.removeStudent())"/> <!--ref:增强的功能所在的类--> <aop:aspect id="logAdvice" ref="adviceMethod"> <!--method:增强的功能具体方法--> <!--pointcut:被增强的切入点的表达式--> <!--<aop:before method="printLog" pointcut="execution(public void com.wuxi.services.impl.StudentServiceImpl.modifyStudent(String))"></aop:before>--> <!--<aop:pointcut id="pt" expression="execution(public void com.wuxi.services.impl.StudentServiceImpl.modifyStudent(String))"/>--> <aop:before method="printLog" pointcut-ref="pt"></aop:before> <aop:around method="printAroundLog" pointcut="execution(public String com.wuxi.services.impl.StudentServiceImpl.findStudent())"></aop:around> </aop:aspect> </aop:config> </beans>
三、要被增强的类的接口
package com.wuxi.services; public interface StudentService { void modifyStudent(String name); String findStudent(); void removeStudent(); }
四、要被增强的类
package com.wuxi.services.impl; import com.wuxi.services.StudentService; public class StudentServiceImpl implements StudentService { @Override public void modifyStudent(String name) { System.out.println("修改" + name); } @Override public String findStudent() { System.out.println("查询"); return "孟美岐"; } @Override public void removeStudent() { System.out.println("删除"); } }
五、增强的功能所在的类(通知类)
package com.wuxi.utils; import org.aspectj.lang.ProceedingJoinPoint; public class LoggerService { public void printLog() { System.out.println("打印日志"); } public Object printAroundLog(ProceedingJoinPoint pjp) { Object proceed = null; try { System.out.println("环绕前置通知"); Object[] args = pjp.getArgs(); proceed = pjp.proceed(args); System.out.println("环绕后置通知"); } catch (Throwable throwable) { System.out.println("环绕异常通知"); throwable.printStackTrace(); } finally { System.out.println("环绕最终通知"); } return proceed; } }
六、测试
package com.wuxi.tests; import com.wuxi.services.StudentService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MySpringTest { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml"); StudentService studentService = (StudentService) ac.getBean("sourceMethod"); // studentService.removeStudent(); studentService.findStudent(); } }
七、APO的理解
APO(面向切面编程)就是在不改变原来方法的原则下,对方法的功能进行增强。思想是使用的是动态代理