项目需求
-
通过日志记录每次accountService业务的执行状况
-
为切入点配置前置通知,异常通知,后置通知,最终通知,环绕通知
项目说明
- 项目使用基于XML的方式配置aop
- 项目不涉及数据库操作,不涉及事务控制,只是简单的关于aop的使用。
- 不涉及真正的日志管理,只是简单模拟日记记录的运行方式
- 项目简单演示了前置通知,异常通知,后置通知,最终通知和环绕通知
- 整合了spring和junit
编写pom文件
使用aop需要导入AspectJ依赖
<?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.cncs</groupId>
<artifactId>day03_04aop_xml_adviceType</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
</project>
新建模拟日志记录类Logger
package com.cncs.utils;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 日志记录类
*/
public class Logger {
/**
* 前置通知
*/
public void beforePrintLog() {
System.out.println("前置....");
}
/**
* 异常通知
*/
public void afterThrowingPrintLog() {
System.out.println("异常....");
}
/**
* 后置通知
*/
public void afterReturningPrintLog() {
System.out.println("后置....");
}
/**
* 最终通知
*/
public void afterPrintLog() {
System.out.println("最终....");
}
public Object aroundPrintLog(ProceedingJoinPoint pjp){
//设置返回值
Object returnVal = null;
//获取参数
Object[] args = pjp.getArgs();
try{
System.out.println("环绕通知....前置");
returnVal = pjp.proceed(args);
System.out.println("环绕通知....后置");
return returnVal;
}catch (Exception e){
System.out.println("环绕通知....异常");
throw new RuntimeException();
} catch (Throwable throwable) {
throwable.printStackTrace();
} finally {
System.out.println("环绕通知....最终");
}
return null;
}
}
新建账户的接口AccountService
package com.cncs.service;
public interface AccountService {
void save();
}
新建账户接口的实现类AccountServiceImpl
package com.cncs.service.impl;
import com.cncs.service.AccountService;
public class AccountServiceImpl implements AccountService {
@Override
public void save() {
// int a = 1/0;
System.out.println("执行了save()...");
}
}
编写spring核心配置文件bean.xml,并配置AOP
<?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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="accountService" class="com.cncs.service.impl.AccountServiceImpl"></bean>
<bean id="log" class="com.cncs.utils.Logger"></bean>
<!--配置AOP-->
<aop:config>
<!--配置切入点表达式-->
<aop:pointcut id="pt1" expression="execution(* com.cncs.service.impl.AccountServiceImpl.*(..))"/>
<aop:aspect id="logAdvice" ref="log">
<!-- <aop:before method="beforePrintLog" pointcut-ref="pt1"></aop:before>-->
<!-- <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>-->
<!-- <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after-returning>-->
<!-- <aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>-->
<aop:around method="aroundPrintLog" pointcut-ref="pt1"></aop:around>
</aop:aspect>
</aop:config>
</beans>
新建测试类AccountTest
package com.cncs.test;
import com.cncs.service.AccountService;
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;
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:bean.xml")
public class AccountTest {
@Autowired
private AccountService accountService;
@Test
public void testAop(){
accountService.save();
}
}