首先导入包(划掉的可以先忽略):
首先,AOP联盟定义的类型分为:
前置通知 org.springframework.aop.MethodBeforeAdvice,在目标方法执行前实施增强(执行切面方法)
后置通知 org.springframework.aop.AfterReturningAdvice,在目标方法执行后实施增强(执行切面方法)
环绕通知 org.aopalliance.intercept.MethodInterceptor,在目标方法执行前后实施增强(执行切面方法)
异常抛出通知 org.springframework.aop.ThrowsAdvice,在方法抛出异常后实施增强(执行切面方法)
引介通知 org.springframework.aop.IntroductionInterceptor,在目标类中添加一些新的方法和属性
其中,环绕通知用的最多。
假设已有如下目标接口和目标类:
public interface UserService { void addUser(); String updateUser(); void deleteUser(); } public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("c_spring_aop add user"); } @Override public void updateUser() { System.out.println("c_spring_aop update user"); } @Override public void deleteUser() { System.out.println("c_spring_aop delete user"); } }
在此基础上,不修改源代码,在调用UserServiceImpl的实例方法前后,输出其他的信息。
首先,新建要给切面类。如下:
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class MyAspect implements MethodInterceptor { @Override public Object invoke(MethodInvocation arg0) throws Throwable { System.out.println("befor..."); Object object = arg0.proceed(); System.out.println("after..."); return object; } }
然后配置文件如下:
<?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" 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"> <bean id="userService" class="com.kye.c_spring_aop.UserServiceImpl"></bean> <bean id="myAspect" class="com.kye.c_spring_aop.MyAspect"></bean> <aop:config> <!--切入点表达式--> <aop:pointcut expression="execution(* com.kye.c_spring_aop.UserServiceImpl.*(..))" id="myPointCut"/> <aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"/> </aop:config> </beans>
其中切入点表达式"execution(* com.kye.c_spring_aop.UserServiceImpl.*(..))"。
第一个* 表示目标函数返回的类型任意
第二个com.kye.c_spring_aop表示包名,可用*代替
第三个UserServiceImpl表示目标类的类名,可用*代替
最后一个*表示目标方法任意,还可以add*
(..)表示目标方法的参数任意,还可以(int,int)
可以同时使用多个切入点表达式用 || 连接
最后测试:
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/c_spring_aop/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...