1、导包
spring-aop:
aopalliance.jar
aspectjrt.jar
aspectjweaver.jar
spring-aop-3.2.5.RELEASE.jar
spring-core:
commons-logging-1.1.3.jar
spring-beans-3.2.5.RELEASE.jar
spring-context-3.2.5.RELEASE.jar
spring-core-3.2.5.RELEASE.jar
spring-expression-3.2.5.RELEASE.jar
2、配置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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="diali"></context:component-scan>
<!-- bean.xml中引入aop名称空间 ,见上面名称空间 xmlns:aop-->
<!-- 开启AOP代理 注解-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
3、创建Interface
public interface IUserDao {
void save();
}
4、创建持久层类(创建两个类,为了区分JDK代理、Cglib代理)
UserDao:
@Component
public class UserDao implements IUserDao {
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("-------------------我是原始方法,不要改变我哈");
}
}
OrderDao:
@Component
public class OrderDao {
public void save(){
System.out.println("------------------我是OrderDao SAVE方法,CGLIB");
}
}
5、创建AOP
@Component//加入IOC容器
@Aspect//指定当前类为切面类
public class Aop {
// 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象
@Pointcut("execution(* diali.*.*(..))")
public void pointCut_(){
}
// 前置通知 : 在执行目标方法之前执行
@Before("pointCut_()")
public void begin(){
System.out.println("目标方法执行前");
}
// 后置/最终通知:在执行目标方法之后执行 【无论是否出现异常最终都会执行】
@After("pointCut_()")
public void after(){
System.out.println("目标方法执行后’");
}
// 返回后通知: 在调用目标方法结束后执行 【出现异常不执行】
@AfterReturning("pointCut_()")
public void afterReturning() {
System.out.println("afterReturning()");
}
// 异常通知: 当目标方法执行异常时候执行此关注点代码
@AfterThrowing("pointCut_()")
public void afterThrowing(){
System.out.println("afterThrowing()");
}
// 环绕通知:环绕目标方式执行(其实与前置通知、后置通知相同,使用其一即可)
@Around("pointCut_()")
public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕前");
pjp.proceed();
System.out.println("环绕后");
}
}
6、测试类
public void testAOP(){
ApplicationContext ac = new ClassPathXmlApplicationContext("diali/bean.xml");
IUserDao userDao = (IUserDao) ac.getBean("userDao");
userDao.save();
System.out.println(userDao.getClass());
System.out.println("\n-----\n");
OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
orderDao.save();
System.out.println(orderDao.getClass());
}
打印结果:
环绕前
目标方法执行前
-------------------我是原始方法,不要改变我哈
环绕后
目标方法执行后’
afterReturning()
class com.sun.proxy.$Proxy11 ------------->JDK代理
-----
环绕前
目标方法执行前
------------------我是OrderDao SAVE方法,CGLIB
环绕后
目标方法执行后’
afterReturning()
class diali.OrderDao$$EnhancerByCGLIB$$a1d32121 --------------------> Cglib代理