注解开发比较方便
配置
需要将项目中的aspectj和aspectjweaver更换为和jdk版本一样的版本
比如我的jdk是1.8,就换为aspectj-1.8.jar和aspectjweaver-1.8.jar,
至于怎么找这个头疼的事,不用去csdn上什么坑人的资源下载,直接去
maven的中央仓库找就行了,使用见下面连接
https://blog.youkuaiyun.com/weixin_36957153/article/details/82964828
记得删除就版本,不然会出错
还得在xml里加上
<!--不扫描,切面类里面加了参数的方法就增强不了-->
<context:component-scan base-package="aop编程"/>
<!--使aop的注解生效-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
ps:proxy-target-class="true"后来加上去的,是为了spring使用aspectj代理,而不是
使用其默认的麻烦的jdk代理,不然得多写几个接口
为了方便,我在测试类里加入
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:/aop编程/aopTest.xml”)
/*
有以上的注解,我们就可以直接在类上进行对象注入
Spring整合Junit
*/
先放下代码
测试类
package aop编程;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
/**
* Created by Administrator on 2018/10/7.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/aop编程/aopTest.xml")
/*
有以上的注解,我们就可以直接在类上进行对象注入
Spring整合Junit
*/
public class testDemo {
@Resource(name="deleUser")
private userDao user;
@Test
public void testDemo1(){
user.add("小明");
user.deleUser("小明");
user.update("小明");
user.save();
}
}
aopTest.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">
<!--需要映入aop的约束-->
<!--不扫描,切面类里面加了参数的方法就增强不了-->
<context:component-scan base-package="aop编程"/>
<!--使aop的注解生效-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<bean id="deleUser" class="aop编程.userDao"></bean>
</beans>
userDao 用户代码,被增强的类
package aop编程;
/**
* Created by Administrator on 2018/10/7.
*/
public class userDao {
public boolean deleUser(String name){
System.out.println(name+"被成功删除deleUser");
return true;
}
public void update(String name){
System.out.println(name+"被更新update");
}
public void save(){
System.out.println("调用userDao.save().....");
int num=1/0;
}
public String add(String name){
System.out.println(name+"被添加进来add");
return "aaaaa";
}
}
切面类
package aop编程;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.omg.CORBA.Object;
import org.springframework.stereotype.Component;
/**
* Created by Administrator on 2018/10/7.
* 切面类
*/
@Component
@Aspect
/*
声明切面类为bean
@Aspect 切面类
* */
public class aspect {
@Pointcut("execution(* aop编程.userDao.add(..))")
private void myPointcut(){
//相当于切点<aop:pointcut expression="execution(* aop编程.userDao.add(..))" id="pointcut2"/>
//为切面类指定切点
}
//通知可以直接在方法上写
@Before(value = "execution(* aop编程.userDao.deleUser(..))&&args(name)")
public void before1(JoinPoint joinPoint,String name){
System.out.println(name+"dele执行前的检测..."+joinPoint);
}
//也可以为方法指定上面写好的切点方法,同样,returning要和方法的参数一样
@AfterReturning(value = "myPointcut()",returning = "result")
public void after1(String result){
System.out.println("执行add方法后..."+result);
}
@Around("execution(* aop编程.userDao.update(..))")
public Object around(ProceedingJoinPoint joinpoint) throws Throwable {
System.out.println("调用update方法前");
Object obj= (Object) joinpoint.proceed();
System.out.println("调用update方法之后");
return obj;
}
@AfterThrowing(value = "execution(* aop编程.userDao.save(..))",throwing = "ex")
public void afterThrow(Throwable ex){
System.out.println("异常被抛出...."+ex.getMessage());
}
@After("execution(* aop编程.userDao.save(..))")
public void finals(){
System.out.println("异常最终被通知");
}
}
这些通知详见上篇博客
https://blog.youkuaiyun.com/weixin_36957153/article/details/82959424
前置通知
@Before(value = “execution(* aop编程.userDao.deleUser(…))&&args(name)”)
加上&&args(name)是为了获取被增强方法的参数
相当于在xml配置了pointcut和切面类(@Component和@Aspect就是声明为
切面类bean交给Spring管理)
后置通知
@Pointcut("execution(* aop编程.userDao.add(..))")
private void myPointcut(){
//相当于切点<aop:pointcut expression="execution(* aop编程.userDao.add(..))" id="pointcut2"/>
//为切面类指定切点
}
//也可以为方法指定上面写好的切点方法,同样,returning要和方法的参数一样
@AfterReturning(value = "myPointcut()",returning = "result")
public void after1(String result){
System.out.println("执行add方法后..."+result);
}
这是另一种指定通知方法(同上)
环绕通知
@Around("execution(* aop编程.userDao.update(..))")
public Object around(ProceedingJoinPoint joinpoint) throws Throwable {
System.out.println("调用update方法前");
Object obj= (Object) joinpoint.proceed();
System.out.println("调用update方法之后");
return obj;
}
异常通知
@AfterThrowing(value = "execution(* aop编程.userDao.save(..))",throwing = "ex")
public void afterThrow(Throwable ex){
System.out.println("异常被抛出...."+ex.getMessage());
}
最终通知
@After("execution(* aop编程.userDao.save(..))")
public void finals(){
System.out.println("异常最终被通知");
}
运行:
ok,perfect