一、使用spring api接口
1.创建一个业务接口(简单的增删改查)
package com.service;
public interface IbookService {
void add();
void del();
void upd();
void find();
}
2. 实现接口
package com.service;
public class IbookServiceImpl implements IbookService {
@Override
public void add() {
System.out.println("增加");
}
@Override
public void del() {
System.out.println("删除");
}
@Override
public void upd() {
System.out.println("修改");
}
@Override
public void find() {
System.out.println("查询");
}
}
3.创建日志类实现MethodBeforeAdvice接口,然后实现里面的方法(前置通知)
package com.log;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
/**
* @author 小宝的宝
*/
public class beforeLog implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println(target.getClass().getName()+"类"+method.getName()+"方法被执行");
}
}
方法中有三个参数
method表示受执行的目标对象的方法、args表示参数、target表示目标对象
4.创建日志类实现AfterReturningAdvice接口,然后实现里面的方法(后置通知)
package com.log;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class AfterLog implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("执行了"+method.getName()+"方法"+"返回值为"+returnValue);
}
}
相比与前置通知,后置通知中多了一个参数,returnValue 表示执行方法后的返回值
5.注册bean对象
<bean id="bookService" class="com.service.IbookServiceImpl"></bean> <bean id="before" class="com.log.beforeLog"></bean> <bean id="after" class="com.log.AfterLog"></bean>
6.配置aop(需要导入aop约束)
<aop:config> <!--expression是一个表达式,execution(要执行的位置)--> <aop:pointcut id="pointcut" expression="execution(* com.service.IbookServiceImpl.*(..))"/> <aop:advisor advice-ref="before" pointcut-ref="pointcut"/> <aop:advisor advice-ref="after" pointcut-ref="pointcut"/> </aop:config>
advice-ref指定哪个通知,pointcut-ref指向执行位置
7.测试
//获取spring上下文对象 ApplicationContext cpx = new ClassPathXmlApplicationContext("applicationContext.xml"); //动态代理的是接口 IbookService bookService =(IbookService) cpx.getBean("bookService"); bookService.add();
8.控制台结果
二、自定义类
1.自己定义一个类(切面类 包含通知)
package com.myLog;
public class MyLog1 {
public void before(){
System.out.println("前置通知");
}
public void after(){
System.out.println("后置通知");
}
}
2.注册bean
<bean id="mylog1" class="com.myLog.MyLog1"></bean> <aop:config> <!--定义切面--> <aop:aspect ref="mylog1"> <!--定义切入点--> <aop:pointcut id="Mypoint" expression="execution(* com.service.IbookServiceImpl.*(..))"/> <!--通知--> <aop:before method="before" pointcut-ref="Mypoint"/> <aop:after method="after" pointcut-ref="Mypoint"/> </aop:aspect> </aop:config>
目标更明确,就是将前置后置通知切入 execution定义的方法下,前置和后置通知在切面中
3.运行结果