此篇文章为aop的全注解配置,xml配置在这里
在注解配置时对照XML文件是十分简单的
根据我的上一篇文章,下面给出注解后的代码
@Service("userService")
public class UserServiceImpl implements IUserService {
@Override
public void findAllUser() {
// int i = 1/0;
System.out.println("执行了查询操作");
}
}
@Component("logger")
@Aspect //配置了切面
public class LoggerTest {
配置文件里的俩个bean是最好解决的,不过在切面类上需要多配置一个@Aspect注解来告知Spring这是切面
接下来就是各种通知的注解配置
@Before
@AfterReturning
@AfterThrowing
@After
@Around
只是看这些注解名称,只要你配置过XML,就知道他们分别就是前置,后置,异常,最终,环绕五个通知
// 前置通知
@Before("log()")
public void beforePrintLog() {
System.out.println("前置通知beforePrintLog执行了");
}
// 后置通知
@AfterReturning("log()")
public void afterReturingPrintLog() {
System.out.println("后置通知afterReturingPrintLog执行了");
}
// 异常通知
@AfterThrowing("log()")
public void afterThrowingPrintLog() {
System.out.println("异常通知afterThrowingPrintLog执行了");
}
// 最终通知
@After("log()")
public void afterPrintLog() {
System.out.println("最终通知afterPrintLog执行了");
}
// 环绕通知
@Around("log()")
public Object aroundPrintLog(ProceedingJoinPoint pjp) {
Object result = null;
try {
System.out.println("前置通知执行了==========");
result = pjp.proceed();
System.out.println("后置通知执行了==========");
} catch (Throwable e) {
System.out.println("异常通知执行了==========");
e.printStackTrace();
}finally {
System.out.println("最终通知执行了==========");
}
return result;
}
那么代码中注解上的log()是什么呢?没错,就是切入点表达式,我们需要额外配置切入点表达式,只需要在这个类里多写一个方法即可
// 切入点表达式
@Pointcut("execution(* com..*.*())")
public void log() {
}
如果此时你想保留XML文件,不想用全注解的方式,那么XML文件里除了配置扫描包外,还需要另一个开启aop注解的配置
<context:component-scan base-package=""></context:component-scan>
<aop:scoped-proxy></aop:scoped-proxy>
这样就行了,不过这种配置我没测试过,我测试的是全注解的方式
全注解的配置我之前在Spring的数据库连接池、IOC和依赖注入的全注解配置这篇文章中写过,
现在我们只需要在原来的基础上加一个注解就行,就是@EnableAspectJAutoProxy注解,看名字也知道对应的是
<aop:scoped-proxy>标签
@Configuration
@ComponentScan("com.aop")
@EnableAspectJAutoProxy //告知Spring找注解切面
public class SpringConfig {
}
不过我在测试过程中出现了问题,我当时就配置切入点表达式时为了省事,配置的是全通配方式* *..*.*(),
结果在测试时,通知执行了俩遍,代码和注解我检查了好几遍,也重新换了一个java工程运行,都是不行,
通过查看别人的博客,我就怀疑是什么我不知道的方法被代理执行了,于是我将目标放在了切入点表达式上,
不用全通配方式,而是将*换成包名,类名,方法名来进行测试,结果通知执行了一遍,最后我发现只要写上
包名就行正常运行。不过由于我个人是刚学习java没多久,还是一个菜鸟,所以我没找出到底是什么被代理
了,如果有大牛看到此篇文章知道这个问题,希望您能将原因在评论里告诉我,万分感谢!!!
此文章为我个人的学习笔记总结,自用