spring_AOP_XML

环境搭建

第一步:
准备客户的业务层和接口(需要增强的类)
/** *
客户的业务层接口*/public interface ICustomerService {
/** * 保存客户 /
void saveCustomer();
/
* * 修改客户 *
@param i /
void updateCustomer(int i);} /
* * 客户的业务层实现类 */
public class CustomerServiceImpl implements ICustomerService {
@Override
public void saveCustomer() {
System.out.println(“调用持久层,执行保存客户”); }
@Override
public void updateCustomer(int i) {
System.out.println(“调用持久层,执行修改客户”); }}
第二步:拷贝必备的jar包到工程的lib目录

第三步:创建spring的配置文件并导入约束

<?xml version="1.0" encoding="UTF-8"?>

第四步:把客户的业务层配置到spring容器中

第五步:制作通知(增强的类)/** * 一个记录日志的工具类*/public class Logger { /** * 期望:此方法在业务核心方法执行之前,就记录日志 */ public void beforePrintLog(){ System.out.println(“Logger类中的printLog方法开始记录日志了。。。。”); }}
配置步骤
第一步:把通知类用bean标签配置起来
第二步:使用aop:config声明aop配置 aop:config </aop:config>
第三步:使用aop:aspect配置切面 <aop:aspect id=“logAdvice” ref=“logger”> </aop:aspect>
第四步:使用aop:before配置前置通知 <aop:before method=“beforePrintLog” pointcut-ref=“pt1”/>
第五步:使用aop:pointcut配置切入点表达式<aop:pointcut expression="execution(public void com.itheima.service.impl.CustomerServiceImpl.saveCustomer())"id=“pt1”/>–>

定义通用的切入点表达式,如果写在aop:aspct标签外部,则表示所有切面可

切入点表达式说明execution: 匹配方法的执行(常用)

execution(表达式)表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))写法说明:

全匹配方式:
public void com.itheima.service.impl.CustomerServiceImpl.saveCustomer() 访问修饰符可以省略 void com.itheima.service.impl.CustomerServiceImpl.saveCustomer() 返回值可以使用号,表示任意返回值 * com.itheima.service.impl.CustomerServiceImpl.saveCustomer() 包名可以使用号,表示任意包,但是有几个包,需要写几个* * ....CustomerServiceImpl.saveCustomer() 使用…来表示当前包,及其子包 * com…CustomerServiceImpl.saveCustomer() 类名可以使用号,表示任意类 * com….saveCustomer() 方法名可以使用号,表示任意方法 * com….() 参数列表可以使用,表示参数可以是任意数据类型,但是必须有参数 * com….()基本类型:直接写类型名称int引用类型:必须是包名.类名java.lang.Integer
参数列表可以使用…表示有无参数均可,有参数可以是任意类型 * com…
.(…) 全通配方式: * .(…) 实际开发中,我们一般情况下,都是对业务层进行增强写法: com.itheima.service.impl ..*(…)
常用标签
aop:config作用: 用于声明开始aop的配置
aop:aspect作用: 用于配置切面。属性: id:给切面提供一个唯一标识。 ref:引用配置好的通知类bean的id。
aop:pointcut作用: 用于配置切入点表达式属性: expression:用于定义切入点表达式。 id:用于给切入点表达式提供一个唯一标识。
aop:before作用: 用于配置前置通知属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用
aop:after-returning作用: 用于配置后置通知属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用
aop:after-throwing作用: 用于配置异常通知属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用
aop:after作用: 用于配置最终通知属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用
aop:around作用: 用于配置环绕通知属性: method:指定通知中方法的名称。 pointct:定义切入点表达式 pointcut-ref:指定切入点表达式的引用
通知的类型类型说明 <aop:before method=“beforePrintLog” pointcut-ref=“pt1”/><aop:after-returning method=“afterReturningPrintLog” pointcut-ref=“pt1”/><aop:after-throwing method=“afterThrowingPrintLog” pointcut-ref=“pt1”/><aop:after method=“afterPrintLog” pointcut-ref=“pt1”/><aop:around method=“aroundPringLog” pointcut-ref=“pt1”/>
环绕通知的特殊说明
/** * 环绕通知 * 它是spring框架为我们提供的一种可以在代码中手动控制增强部分什么时候执行的方式。 * 问题: * 当我们配置了环绕通知之后,增强的代码执行了,业务核心方法没有执行。 * 分析: * 通过动态代理我们知道在invoke方法中,有明确调用业务核心方法:method.invoke()。 * 我们配置的环绕通知中,没有明确调用业务核心方法。 * 解决: * spring框架为我们提供了一个接口:ProceedingJoinPoint,它可以作为环绕通知的方法参数 * 在环绕通知执行时,spring框架会为我们提供该接口的实现类对象,我们直接使用就行。 * 该接口中有一个方法proceed(),此方法就相当于method.invoke() */ public void aroundPringLog(ProceedingJoinPoint pjp){ try { System.out.println(“前置通知:Logger类的aroundPringLog方法记录日志”); pjp.proceed(); System.out.println(“后置通知:Logger类的aroundPringLog方法记录日志”); } catch (Throwable e) { System.out.println(“异常通知:Logger类的aroundPringLog方法记录日志”); e.printStackTrace(); }finally{ System.out.println(“最终通知:Logger类的aroundPringLog方法记录日志”); } }

基于注解的AOP配置

环境搭建

第一步:准备客户的业务层和接口并用注解配置(需要增强的类)/** * 客户的业务层接口*/public interface ICustomerService { /** * 保存客户 / void saveCustomer(); /* * 修改客户 * @param i / void updateCustomer(int i);} /* * 客户的业务层实现类 /public class CustomerServiceImpl implements ICustomerService { @Override public void saveCustomer() { System.out.println(“调用持久层,执行保存客户”); } @Override public void updateCustomer(int i) { System.out.println(“调用持久层,执行修改客户”); }}
第二步:拷贝必备的jar包到工程的lib目录
第三步:创建spring的配置文件并导入约束<?xml version="1.0" encoding="UTF-8"?>
第四步:把资源使用注解让spring来管理/
* * 客户的业务层实现类 */@Service(“customerService”)public class CustomerServiceImpl implements ICustomerService { @Override public void saveCustomer() { System.out.println(“调用持久层,执行保存客户”); } @Override public void updateCustomer(int i) { System.out.println(“调用持久层,执行修改客户”); }}
第五步:在配置文件中指定spring要扫描的包 <context:component-scan base-package=“com.itheima”></context:component-scan>

配置步骤

第一步:把通知类也使用注解配置/** * 一个记录日志的工具类 /@Component(“logger”)public class Logger { /* * 期望:此方法在业务核心方法执行之前,就记录日志 * 前置通知 / public void beforePrintLog(){ System.out.println(“前置通知:Logger类中的printLog方法开始记录日志了”); }}
第二步:在通知类上使用@Aspect注解声明为切面/
* * 一个记录日志的工具类 /@Component(“logger”)@Aspect//表明当前类是一个切面类public class Logger { /* * 期望:此方法在业务核心方法执行之前,就记录日志 * 前置通知 / public void beforePrintLog(){ System.out.println(“前置通知:Logger类中的printLog方法开始记录日志了”); }}
第三步:在增强的方法上使用@Before注解配置前置通知 /
* * 期望:此方法在业务核心方法执行之前,就记录日志 * 前置通知 / @Before("execution( com.itheima.service.impl..(…))")//表示前置通知 public void beforePrintLog(){ System.out.println(“前置通知:Logger类中的printLog方法开始记录日志了”); }
第四步:在spring配置文件中开启spring对注解AOP的支持 aop:aspectj-autoproxy/

常用注解

@Aspect:作用: 把当前类声明为切面类。
@Before:作用: 把当前方法看成是前置通知。属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterReturning作用: 把当前方法看成是后置通知。属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@AfterThrowing作用: 把当前方法看成是异常通知。属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@After作用: 把当前方法看成是最终通知。属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@Around作用: 把当前方法看成是环绕通知。属性: value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@Pointcut作用: 指定切入点表达式属性: value:指定表达式的内容
不使用XML的配置方式@Configuration@ComponentScan(basePackages=“com.itheima”)@EnableAspectJAutoProxypublic class SpringConfiguration {}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值