三种方式使用spring实现AOP(实际上以后要自己单独写aop的机会也不会太多,但是也要了解Spring的aop)
第三种方式——通过注解来实现
需要导入Spring AOP api的依赖jar包,可以在老的Spring lib(如2.5)里面找到
aopalliance.jar
aspectjweaver.jar
在beans.xml里面需要导入aop的命名空间并在XML catalog里面配置好
log.java
@Aspect
public class Log{
@Before("execution(* cn.sxt.service.*.*(..))")
public void before(){
System.out.println("------方法执行前--------");
}
@After("execution(* cn.sxt.service.*.*(..))")
public void after(){
System.out.println("------方法执行后--------");
}
@Around("execution(* cn.sxt.service.*.*(..))")
public Object around(ProceedingJoinPoint jp) throws Throwable{
System.out.println("环绕前");
System.out.println("签名"+jp.getSignature());
//执行目标方法
Object result=jp.proceed();
System.out.println("环绕后");
return result;
}
}
beans.xml
<bean id="userService" class="cn.sxt.service.UserServiceImpl"></bean>
<bean id="log" class="cn.sxt.log.Log"></bean>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
public class UserServiceImpl implements UserService{
@Override
public int add() {
System.out.println("增加用户");
return 1;
}
@Override
public void update() {
System.out.println("修改用户");
}
@Override
public void delete() {
System.out.println("删除用户");
}
@Override
public void search() {
System.out.println("查询用户");
}
}
测试:
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
UserService userService=(UserService)ac.getBean("userService");
userService.add();
}
}
结果:
环绕前
签名int cn.sxt.service.UserService.add()
------方法执行前--------
增加用户
环绕后
------方法执行后--------
调试记载:
1 . 使用注解只需要在xml配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
在切面类上用注解标注,在方法上表名通知类型和横切点
2 .注意环绕方法
需要在里面执行目标方法而且要返回类型,否则报错
@Around("execution(* cn.sxt.service.*.*(..))")
public Object around(ProceedingJoinPoint jp) throws Throwable{
System.out.println("环绕前");
System.out.println("签名"+jp.getSignature());
//执行目标方法
Object result=jp.proceed();
System.out.println("环绕后");
return result;
}
3 .分析结果:执行环绕,因为环绕里面要写明执行方法,所以是按顺序执行,先输出环绕前,这时候要执行目标方法了,执行before,然后继续按顺序执行,因为后置通知是return之后,所以后置通知最后执行。如果你把System.out.println("环绕前")
放到执行目标方法语句后面就会发现环绕前三个字出现在目标方法执行结果输出之后。
环绕前
------方法执行前--------
增加用户
签名int cn.sxt.service.UserService.add()
环绕后
------方法执行后--------
4 .签名就是方法签名,把方法的信息写出了,就跟人签名一样