一、使用注解方式实现AOP – 步骤
1.1 先引入spring-core ,spring-aop相关jar文件 (aspectj aop优秀组件)
spring-aop-3.2.5.RELEASE.jar 【spring3.2源码】
aopalliance.jar 【spring2.5源码/lib/aopalliance】
aspectjweaver.jar 【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
aspectjrt.jar 【spring2.5源码/lib/aspectj】或【aspectj-1.8.2\lib】
注意: spring3.0 以上没有相关组件依赖包,
spring3.0以下才有相关组件依赖包。
用到spring2.5版本的jar文件,如果用jdk1.7可能会有问题。
需要升级aspectj组件,即使用aspectj-1.8.2版本中提供jar文件提供。
1.2 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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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/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">
</beans>
1.3 开启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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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/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">
<!-- 开启注解扫描 -->
<context:component-scan base-package="org.jsoft"></context:component-scan>
<!-- 开启aop注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
1.4 使用注解
@Aspect
指定一个类为切面类
@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
指定切入点表达式
@Before("pointCut_()") 前置通知: 目标方法之前执行
@After("pointCut_()") 后置通知:目标方法之后执行(始终执行)
@AfterReturning("pointCut_()") 返回后通知: 执行方法结束前执行(异常不执行)
@AfterThrowing("pointCut_()") 异常通知: 出现异常时候执行
@Around("pointCut_()") 环绕通知: 环绕目标方法执行
1.5 案例
>>>>>> applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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/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">
<!-- 开启注解扫描 -->
<context:component-scan base-package="org.jsoft"></context:component-scan>
<!-- 开启aop注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
>>>>>> UserDao .java
@Repository
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("DB 保存");
}
}
>>>>>> Aop .java
@Component
@Aspect
public class Aop {
@Before("execution(* org.jsoft.d_proxy_f_aop_anno.UserDao.*(..))")
public void begin() {
System.out.println("开启事务");
}
@After("execution(* org.jsoft.d_proxy_f_aop_anno.UserDao.*(..))")
public void end() {
System.out.println("关闭事务");
}
}
>>>>>> AppTest.java
public class AppTest{
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/d_proxy_f_aop_anno/applicationContext.xml");
IUserDao proxy =(IUserDao) ac.getBean("userDao");
proxy.save();
}
}
二、使用注解方式实现AOP – 详解
2.1 切入点的设置
2.1.1 方法上直接指定切入点表达式
@Component
@Aspect
public class Aop {
@Before("execution(* org.jsoft.d_proxy_f_aop_anno.UserDao.*(..))")
public void begin() {
System.out.println("开启事务");
}
@After("execution(* org.jsoft.d_proxy_f_aop_anno.UserDao.*(..))")
public void end() {
System.out.println("关闭事务");
}
}
2.1.2 方法上引用切入点表达式
@Component
@Aspect
public class Aop {
@Pointcut("execution(* org.jsoft.d_proxy_f_aop_anno.UserDao.*(..))")
public void point1() {
}
@Before("point1()")
public void begin() {
System.out.println("开启事务");
}
@After("point1()")
public void end() {
System.out.println("关闭事务");
}
}
2.2 通知类型
指定一个类为切面类 @Aspect
指定切入点表达式
@Pointcut("execution(* cn.itcast.e_aop_anno.*.*(..))")
前置通知: 目标方法之前执行
@Before("pointCut_()")
后置通知:目标方法之后执行(无论目标方法是否异常,都会执行)
@After("pointCut_()")
返回后通知:目标方法之后执行(目标方法出现异常,就不执行)
@AfterReturning("pointCut_()")
异常通知: 目标方法出现异常,才会执行
@AfterThrowing("pointCut_()")
环绕通知: 环绕目标方法执行(相当于前置+后置)
@Around("pointCut_()")
2.3 案例
>>>>>> applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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/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">
<!-- 开启注解扫描 -->
<context:component-scan base-package="org.jsoft"></context:component-scan>
<!-- 开启aop注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
>>>>>> UserDao .java
@Repository
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("DB 保存");
}
}
>>>>>> Aop .java
@Component
@Aspect
public class Aop {
@Pointcut("execution(* org.jsoft.d_proxy_f_aop_anno.UserDao.*(..))")
public void point1() {
}
//前置通知:在调用目标方法之前执行
@Before("point1()")
public void begin() {
System.out.println("开启事务");
}
//后置通知:在调用目标方法结束之后执行【无论目标方法是否出现异常,都执行】
@AfterReturning("point1()")
public void end() {
System.out.println("关闭事务");
}
//返回后通知:在调用目标方法结束之后执行【出现异常不执行】
@AfterReturning("point1()")
public void afterReturing() {
System.out.println("afterReturing");
}
//异常通知:执行目标方法之后执行,目标方法抛出异常,就不执行【出现异常才执行】
@AfterThrowing("point1()")
public void afeterThrowing() {
System.out.println("afeterThrowing");
}
//环绕通知
@Around("point1()")
public void around(ProceedingJoinPoint point) throws Throwable {
System.out.println("环绕前");
point.proceed();
System.out.println("环绕后");
}
}
>>>>>> AppTest.java
public class AppTest{
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("org/jsoft/d_proxy_f_aop_anno/applicationContext.xml");
IUserDao proxy =(IUserDao) ac.getBean("userDao");
proxy.save();
}
}
1