导包请参考这里
假设有如下目标接口和目标类:
public interface UserService { void addUser(); String updateUser(); void deleteUser(); } import org.springframework.stereotype.Service; @Service("userService") public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println(" add user"); } @Override public String updateUser() { System.out.println(" update user"); return "更新用户信息"; } @Override public void deleteUser() { System.out.println(" delete user"); int a = 1/0; } }
新建切面类:
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Component() @Aspect() public class MyAspect { // 定义公共切入点表达式 @Pointcut("execution(* com.kye.d_aspect.b_annotation.UserServiceImpl.*(..))") private void myPointCutExpress() { } @Before("execution(* com.kye.d_aspect.b_annotation.UserServiceImpl.*(..))") public void myBefor(JoinPoint joinPoint) { System.out.println("前置通知"); } @AfterReturning(value = "myPointCutExpress()", returning = "object") public void myReturn(JoinPoint joinPoint, Object object) { System.out.println("后置通知,返回的值为:" + object); } @Around(value = "myPointCutExpress()") public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕前 通知:"+joinPoint.getSignature().getName()); Object object = joinPoint.proceed(); System.out.println("环绕后通知:"+joinPoint.getSignature().getName()); return object; } @AfterThrowing(value = "myPointCutExpress()", throwing = "eThrowable") public void myThrowAble(JoinPoint joinPoint, Throwable eThrowable) { System.out.println("异常通知:" + eThrowable.getMessage()); } }
配置文件如下:
<?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"> <!-- 有注解和xml id同名时,xml会覆盖注解 --> <!-- <bean id="userService" class="com.kye.d_aspect.b_annotation.UserServiceImpl2" ></bean> --> <context:component-scan base-package="com.kye.d_aspect.b_annotation"></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
新建测试类:
import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { @Test public void test1() { String path = "com/kye/d_aspect/b_annotation/beans.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path); UserService userService = applicationContext.getBean("userService", UserService.class); userService.addUser(); userService.updateUser(); userService.deleteUser(); } }
输出结果:
befor... c_spring_aop add user after... befor... c_spring_aop update user after... befor... c_spring_aop delete user after...
另外我还尝试了一下,假设xml和注解中,存在同名的id,最后xml会覆盖注解。