一、Spring AOP的注解开发
第一步:首先编写我们的业务接口和实现类
接口:
package com.itheima.anno;
public interface TargetInterface {
public void save();
}
```java
实现类:
package com.itheima.anno;
import org.springframework.stereotype.Component;
@Component("target")
public class Target implements TargetInterface{
@Override
public void save() {
System.out.println("save running...");
}
}
使用@Component(“target”)注入bean
第二步:编写一个注解实现的增强类
package com.itheima.anno;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component("MyAspect")
@Aspect
public class MyAspect {
//配置前置通知
@Before("execution(* com.itheima.anno.*.*(..))")
public void before(){
System.out.println("前置增强..........");
}
public void afterReturning(){
System.out.println("后置增强..........");
}
//正在执行的连接点ProceedingJoinPoint == 切点
@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前增强.....");
Object proceed = pjp.proceed();
System.out.println("环绕后增强....");
return proceed;
}
public void afterThrowing(){
System.out.println("异常抛出增强.....");
}
@After("execution(* com.itheima.anno.*.*(..))")
public void after(){
System.out.println("最终增强.....");
}
//定义切点抽取表达式
@Pointcut("execution(* com.itheima.anno.*.*(..))")
public void pointcut(){
}
}
在使用注解时可以定义一个切点表达式,省去每次注解后加入的包地址以及类方法,例如:@Around("execution( com.itheima.anno..(…))")
定义后可以使用@Around(“pointcut()”)代替,方便了后期的维护。*
二、配置spring.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
">
<!--组件扫描-->
<context:component-scan base-package="com.itheima.anno"/>
<!--aop自动代理-->
<aop:aspectj-autoproxy/>
</beans>
必须得在spring文件中加入组件扫描识别类中的注解,同时aop的自动代理配置也是不能少的
三、测试
测试类:
package com.itheima.test;
import com.itheima.anno.TargetInterface;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-anno.xml")
public class annoTest {
@Autowired
private TargetInterface target;
@Test
public void test1(){
target.save();
}
}
运行结果为:
环绕前增强…
前置增强…
save running…
环绕后增强…
最终增强…
知识要点
利用注解去使用aop的方法加强,减少的代码的重复。
前置通知 | @Before 用于配置前置通知,指定增强的方法在切入点方法之前执行 |
---|---|
后置通知 | @AfterReturning 用于配置后置通知,指定增强的方法在切入点方法之后执行 |
环绕通知 | @Around 用于配置环绕通知,指定增强方法在出现异常时执行 |
异常抛出通知 | @After Throwing 用于配置异常抛出通知,指定增强的方法在出现异常时执行 |
最终通知 | @After 用于配置最终通知,无论增强方法执行是否有异常都会执行 |