1.1 项目目录
1.2 代码实现
CustomerService
package cn.guardwhy.service;
/**
* 客户service接口
*/
public interface CustomerService {
/**
* 保存客户
*/
void saveCustomer();
/**
* 根据客户id查询客户
*/
void findCustomerById(Integer id);
}
CustomerServiceImpl
package cn.guardwhy.service.impl;
import cn.guardwhy.service.CustomerService;
import org.springframework.stereotype.Service;
/**
* 客户service实现类
*/
@Service("customerService")
public class CustomerServiceImpl implements CustomerService {
@Override
public void saveCustomer() {
System.out.println("保存客户操作");
}
@Override
public void findCustomerById(Integer id) {
// 根据客户id查询客户
System.out.println("根据客户id查询客户,客户id: " + id);
}
}
LogAdvice
package cn.guardwhy.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 日志通知类
* 注解说明:
* @Aspect:
* 作用:声明当前类是一个切面类,相当于xml中aop:aspect标签
* @Before:
* 作用:配置前置通知
* @AfterReturning:
* 作用:配置后置通知
* @AfterThrowing:
* 作用:配置异常通知
* @After:
* 作用:配置最终通知
* @Pointcut:
* 作用:配置切入点表达式
*/
@Component("logAdvice")
@Aspect
public class LogAdvice {
/**
* 切入点表达式
*/
@Pointcut("execution(* cn.guardwhy.service..*.*(..))")
public void pt1(){}
/**
* 前置通知
*/
@Before("pt1()")
public void beforeLog(){
System.out.println("[前置通知]记录用户操作日志");
}
/**
* 后置通知
*/
@AfterReturning("pt1()")
public void afterReturningLog(){
System.out.println("【后置通知】记录用户操作日志");
}
/**
* 异常通知
*/
@AfterThrowing("pt1()")
public void afterThrowingLog(){
System.out.println("【异常通知】记录用户操作日志");
}
/**
* 最终通知
*/
@After("pt1()")
public void afterLog(){
System.out.println("【最终通知】记录用户操作日志");
}
/**
* 环绕通知:
* 1.它是spring框架为我们提供了手动控制通知执行时间点和顺序的一种特殊通知类型
* 原理分析:
* 2.spring框架提供了ProceedingJoinPoint接口,作为环绕通知的参数。在环绕通知
* 执行的时候,spring框架会提供实例化对象,我们直接使用即可。该接口中提供了
* 两个方法:
* getArgs:获取参数列表
* proceed:相当于反射中的invoke方法
*
*/
@Around("pt1()")
public void aroundLog(ProceedingJoinPoint pjp){
// 前置通知
System.out.println("[环绕通知-前置通知]记录用户操作日志");
try {
// 获取参数列表
Object[] args = pjp.getArgs();
// 反射调用目标方法
Object retv = pjp.proceed(args);
// 后置通知
System.out.println("[环绕通知-后置通知]记录用户操作日志");
} catch (Throwable throwable) {
throwable.printStackTrace();
// 异常通知
System.out.println("[环绕通知-异常通知]记录用户操作日志");
}
// 最终通知
System.out.println("[环绕通知-最终通知]记录用户操作日志");
}
}
13.5.4 配置bean.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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--配置包扫描advice/service,说明:
第一步:导入context名称空间和约束
第二步:通过<context:component-scan>标签配置包扫描
-->
<context:component-scan base-package="cn.guardwhy"/>
<!--关键步骤:开启spring对注解aop支持-->
<aop:aspectj-autoproxy/>
</beans>
CustomerController
package cn.guardwhy.controller;
import cn.guardwhy.service.CustomerService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 客户表现层
*/
public class CustomerController {
public static void main(String[] args) {
// 1.加载spring的配置文件,创建spring的ioc容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");
// 2.获取客户service
CustomerService customerService = (CustomerService)context.getBean("customerService");
// 3.保存客户
customerService.saveCustomer();
// 根据客户id查询客户
// customerService.findCustomerById(1);
}
}
执行结果