那些类允许增强的表达式
语法:execution(表达式)
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
[*代表方法的返回值为任意类型] [*代表所有方法] [..代表任意参数类型]
execution(* cn.itcast.spring3.demo1.dao.*(..)) —只检索当前包
execution(* cn.itcast.spring3.demo1.dao..*(..)) —检索包及当前包的子包.
execution(* cn.itcast.dao.GenericDAO+.*(..)) —检索 GenericDAO 及子类
匹配所有类 public 方法 execution(public * *(..))
匹配指定包下所有类方法 execution(* cn.itcast.dao.*(..)) 不包含子包
execution(* cn.itcast.dao..*(..)) ..*表示包、 子孙包下所有类
匹配指定类所有方法 execution(*cn.itcast.service.UserService.*(..))
匹配实现特定接口所有类方法execution(*cn.itcast.dao.GenericDAO+.*(..))
匹配所有 save 开头的方法 execution(* save*(..))
@Before 前置通知, 相当于 BeforeAdvice
@AfterReturning 后置通知, 相当于 AfterReturningAdvice
@Around 环绕通知, 相当于 MethodInterceptor
@AfterThrowing 抛出通知, 相当于 ThrowAdvice
@After 最终 final 通知, 不管是否异常, 该通知都会执行
@DeclareParents 引介通知, 相当于 IntroductionInterceptor

<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-testartifactId>
<version>${spring.version}version>
dependency>
<dependency>
<groupId>org.aspectjgroupId>
<artifactId>aspectjweaverartifactId>
<version>1.9.4version>
dependency>
@Repository(value = "userDao") //注解的方式,spring管理对象的创建
public class UserDao {
public void add(){
System.out.println("添加用户");
}
public void addInfo(){
System.out.println("添加用户信息");
}
public void update(){
System.out.println("更新用户");
}
public void delete(){
System.out.println("删除用户");
}
public void find(){
System.out.println("查找用户");
}
}
@Component // 注解的方式,spring管理对象的创建
@Aspect // 用来定义且切面
public class MyAspectJ {
/**
* 前置通知
* 对UserDao里面的以add方法进行增强
* @param joinPoint
*/
@Before("execution(* club.krislin.Dao.UserDao.add*(..))")
public void before(JoinPoint joinPoint){
//打印的是切点信息
System.out.println(joinPoint);
System.out.println("前置增强");
}
/**
* 后置通知
* 对update开头的方法进行增强
* @param returnValue
*/
@AfterReturning(value = "execution(* club.krislin.Dao.UserDao.update*(..))",returning = "returnValue") // 接受返回值,方法的返回值为任意类型
public void after(Object returnValue){
System.out.println("后置通知");
System.out.println("方法的返回值为:"+returnValue);
}
/**
* 环绕通知增强
* 对以find开头的方法进行增强
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
@Around(value = "execution(* club.krislin.Dao.UserDao.find*(..))")
public Object arount(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕通知增强-----前");
// 执行目标方法
Object obj = proceedingJoinPoint.proceed();
System.out.println("环绕通知增强-----后");
return obj;
}
/**
* 异常通知增强
* 对以find开头的方法进行增强
* @param e
*/
@AfterThrowing(value = "execution(* club.krislin.Dao.UserDao.find(..))",throwing = "e")
public void afterThrowing(Throwable e){
System.out.println("出现异常"+e.getMessage());
}
@After(value = "execution(* club.krislin.Dao.UserDao.find(..))")
public void after(){
System.out.println("最终通知");
}
}
<aop:aspectj-autoproxy>aop:aspectj-autoproxy>
<context:component-scan base-package="club.krislin">context:component-scan>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserDaoTest {
@Resource(name = "userDao")
private UserDao userDao;
@Test
public void testUserDao(){
userDao.add();
userDao.addInfo();
userDao.delete();
userDao.find();
userDao.update();
}
}
public class UserDao {
public void add(){
System.out.println("添加用户");
}
public void addInfo(){
System.out.println("添加用户信息");
}
public void update(){
System.out.println("更新用户");
}
public void delete(){
System.out.println("删除用户");
}
public void find(){
System.out.println("查找用户");
//int i = 1;
//int n = i/0;
}
}
public class MyAspectJ {
/**
* 前置通知
* @param joinPoint
*/
public void before(JoinPoint joinPoint){
//打印的是切点信息
System.out.println(joinPoint);
System.out.println("前置增强");
}
/**
* 后置通知
* @param returnValue
*/
public void after(Object returnValue){
System.out.println("后置通知");
System.out.println("方法的返回值为:"+returnValue);
}
/**
* 环绕通知增强
* @param proceedingJoinPoint
* @return
* @throws Throwable
*/
public Object arount(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕通知增强-----前");
// 执行目标方法
Object obj = proceedingJoinPoint.proceed();
System.out.println("环绕通知增强-----后");
return obj;
}
/**
* 异常通知增强
* @param e
*/
public void afterThrowing(Throwable e){
System.out.println("出现异常"+e.getMessage());
}
/**
* 最终通知增强
*/
public void after(){
System.out.println("最终通知");
}
}
<bean name="userDao" class="club.krislin.Dao.UserDao">bean>
<bean name="myAspectJ" class="club.krislin.MyAspectJ">bean>
<aop:config>
<aop:pointcut expression="execution(* club.krislin.Dao.UserDao.add*(..))" id="myPointcut"/>
<aop:pointcut expression="execution(* club.krislin.Dao.UserDao.add(..))" id="myPointcut1"/>
<aop:aspect ref="myAspectJ">
<aop:before method="before" pointcut-ref="myPointcut"/>
aop:aspect>
<aop:aspect ref="myAspectJ">
<aop:after-returning method="after" pointcut-ref="myPointcut" returning="returnValue"/>
aop:aspect>
<aop:aspect ref="myAspectJ">
<aop:around method="arount" pointcut-ref="myPointcut"/>
aop:aspect>
<aop:aspect ref="myAspectJ">
<aop:after-throwing method="afterThrowing" pointcut-ref="myPointcut" throwing="e"/>
aop:aspect>
<aop:aspect ref="myAspectJ">
<aop:after method="after" pointcut-ref="myPointcut1"/>
aop:aspect>
aop:config>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class UserDaoTest {
@Resource(name = "userDao")
private UserDao userDao;
@Test
public void testUserDao(){
userDao.add();
userDao.addInfo();
userDao.delete();
userDao.update();
userDao.find();
}
}
aop:config声明aop配置aop:config 用于声明开始aop的配置
<aop:config>
aop:config>
aop:aspect配置切面aop:aspect 用于配置切面
属性: id:给切面提供一个唯一的表示
ref:引用配置好的通知类bean的id
<aop:aspect id="txAdvice" ref="txManager">
aop:aspect>
aop:pointcut配置切入点表达式aop:pointcut 用于配置切入点表达式.就是指定对哪些类的哪些方法进行增强
属性: expression:由于定义切入表达式
id:用于给切入点表达式提供唯一的标识
<aop:pointcut expression="execution(* club.krislin.Dao.UserDao.add*(..))" id="myPointcut"/>
aop:xxx配置对应的通知类型aop:before 用于配置前置通知.指定增强的方法在切入点方法之前执行
属性: method:用于指定通知类中的增强方法名称
pointcut-ref:用于指定切入点表达式的引用
pointcut:用于指定切入点表达式
执行时间: 切入点方法执行之前
<aop:before method="before" pointcut-ref="myPointcut"/>
aop:after-returning 用于配置后置通知
属性: method:用于指定通知类中的增强方法名称
pointcut-ref:用于指定切入点表达式的引用
pointcut:用于指定切入点表达式
returning:后置通知返回值
执行时间:切入点方法正常执行之后,它和异常通知只能有一个执行
<aop:after-returning method="after" pointcut-ref="myPointcut" returning="returnValue"/>
aop:after-throwing 用于配置异常通知
属性: method:用于指定通知类中的增强方法名称
pointcut-ref:用于指定切入点表达式的引用
pointcut:用于指定切入点表达式
throwing:指定抛出的异常
执行时间:切入点方法执行异常后执行,它和后置通知只能有一个执行
<aop:after-throwing method="afterThrowing" pointcut-ref="myPointcut" throwing="e"/>
aop:after: 用于配置最终通知
属性: method:用于指定通知类中的增强方法名称
pointcut-ref:用于指定切入点表达式的引用
pointcut:用于指定切入点表达式
执行时间:无论切入点方法执行时是否异常,它都会在后面执行
<aop:after method="after" pointcut-ref="myPointcut1"/>
aop:around 用于配置环绕通知
属性: method:用于指定通知类中的增强方法名称
pointcut-ref:用于指定切入点表达式的引用
pointcut:用于指定切入点表达式
<aop:around method="arount" pointcut-ref="myPointcut"/>