包:aspectjrt.jar、aspectjweaver.jar
AOP:面向切面的编程
1.XML配置;
2.注解。
一、注解方式:
打开注解处理器:
<aop:aspectj-autoproxy/>
接口:
1 package com.dwr.spring.proxy; 2 3 public interface UserManager { 4 public void addUser(String username,String password); 5 public void deleteUser(int userid); 6 public void modifyUser(int userid,String username,String password); 7 public void findUser(int userid); 8 }
实现类:
1 package com.dwr.spring.proxy; 2 3 public class UserManagerImpl implements UserManager { 4 @Override 5 public void addUser(String username, String password) { 6 System.out.println("--------UserManagerImpl.addUser()----------"); 7 } 8 9 @Override 10 public void deleteUser(int userid) { 11 System.out.println("--------UserManagerImpl.deleteUser()----------"); 12 } 13 14 @Override 15 public void modifyUser(int userid, String username, String password) { 16 System.out.println("--------UserManagerImpl.modifyUser()----------"); 17 } 18 19 @Override 20 public void findUser(int userid) { 21 System.out.println("--------UserManagerImpl.findUser()----------"); 22 } 23 }
切面类:使用@Aspect来标识
在切面类中定义切入点(定义要拦截的方法)
@Pointcut("execution(* com.dwr.spring..*.*(..))")
execution:代表执行;
第一个*:返回值类型;
com.dwr.spring:包名;
..:对子包也拦截
第二个*:代表所有类;
第三个*:代表所有方法。
最后的..:代表方法的参数可有可无。
定义切面类:注意注解的写法,通知。注意切入点的名称包括括号
1 package com.dwr.spring.test; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 import org.aspectj.lang.annotation.*; 5 6 @Aspect 7 public class Interceptor { 8 9 //定义切入点:对UserManagerImpl类的所有方法进行拦截 10 @Pointcut("execution(* com.dwr.spring.proxy.UserManagerImpl.*(..))") 11 private void anyMethod(){ //切入点的名称:anyMethod() 12 13 } 14 15 @Before("anyMethod()") 16 public void doBefore(){ 17 System.out.println("执行前通知"); 18 } 19 20 @AfterReturning("anyMethod()") 21 public void doAfterReturning(){ 22 System.out.println("执行后通知"); 23 } 24 25 @After("anyMethod()") 26 public void doAfter(){ 27 System.out.println("执行最终通知"); 28 } 29 @AfterThrowing("anyMethod()") 30 public void afterThrowing(){ 31 System.out.println("意外通知"); 32 } 33 34 @Around("anyMethod()") 35 public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { 36 System.out.println("进入环绕判断方法"); 37 Object result = proceedingJoinPoint.proceed(); 38 System.out.println("退出环绕判断方法"); 39 return result; 40 } 41 }
配置xml文件:打开注解处理器、配置bean
1 <aop:aspectj-autoproxy/> 2 3 <bean id="userManagerImpl" class="com.dwr.spring.proxy.UserManagerImpl"></bean> 4 <bean id="interceptor" class="com.dwr.spring.test.Interceptor"></bean>
测试:
1 package com.dwr.spring.test; 2 3 import com.dwr.spring.proxy.UserManager; 4 import org.springframework.context.ApplicationContext; 5 import org.springframework.context.support.ClassPathXmlApplicationContext; 6 7 public class TestInterceptor { 8 9 public static void main(String[] args){ 10 11 ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml"); 12 UserManager userManager = (UserManager) context.getBean("userManagerImpl"); 13 userManager.addUser("Jack","123456"); 14 } 15 }
结果:
进入环绕判断方法
执行前通知
--------UserManagerImpl.addUser()----------
退出环绕判断方法
执行最终通知
执行后通知
二、配置文件方式:
类:
1 package com.dwr.spring.test; 2 3 import org.aspectj.lang.ProceedingJoinPoint; 4 5 public class NewInterceptor { 6 public void doBefore(){ 7 System.out.println("执行前通知"); 8 } 9 public void doAfterReturning(){ 10 System.out.println("执行后通知"); 11 } 12 public void doAfter(){ 13 System.out.println("执行最终通知"); 14 } 15 public void afterThrowing(){ 16 System.out.println("意外通知"); 17 } 18 public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { 19 System.out.println("进入环绕判断方法"); 20 Object result = proceedingJoinPoint.proceed(); 21 System.out.println("退出环绕判断方法"); 22 return result; 23 } 24 }
xml文件的配置:
1 <bean id="userManagerImpl" class="com.dwr.spring.proxy.UserManagerImpl"></bean> 2 <bean id="aspectbean" class="com.dwr.spring.test.NewInterceptor"></bean> 3 <aop:config> 4 <aop:aspect id="aspect" ref="aspectbean"> 5 <aop:pointcut id="cut" expression="execution(* com.dwr.spring.proxy.UserManagerImpl.*(..))"/> 6 <aop:before method="doBefore" pointcut-ref="cut"/> 7 <aop:after-returning method="doAfterReturning" pointcut-ref="cut"/> 8 <aop:after method="doAfter" pointcut-ref="cut"/> 9 <aop:after-throwing method="afterThrowing" pointcut-ref="cut"/> 10 <aop:around method="doAround" pointcut-ref="cut"/> 11 </aop:aspect> 12 </aop:config>
测试代码与上面相同:
结果:
执行前通知
进入环绕判断方法
--------UserManagerImpl.addUser()----------
退出环绕判断方法
执行最终通知
执行后通知