-----------------------------基于XML配置方案
目标对象接口
1 public interface IUserService { 2 public void add(); 3 public void update(); 4 public void del(); 5 public void search(); 6 }
1.创建目标对象
1 public class UserServiceImpl implements IUserService { 2 @Override 3 public void add() { 4 System.out.println("add...."); 5 } 6 @Override 7 public void update() { 8 System.out.println("update...."); 9 } 10 @Override 11 public void del() { 12 System.out.println("del...."); 13 } 14 @Override 15 public void search() { 16 System.out.println("search...."); 17 } 18 }
2.创建通知(增强 advice)
1 //adcice增强类 Aspectj框架定义的通知类型 2 public class UserServiceHelper { 3 //前置通知 4 public void before(JoinPoint jp){ 5 System.out.println("拦截目标类"+jp.getSignature().getDeclaringTypeName()); 6 System.out.println("拦截目标方法名"+jp.getSignature().getName()); 7 System.out.println("前置通知"); 8 9 } 10 public void afterreturning(JoinPoint jp,Object val){ 11 System.out.println("目标返回值"+val); 12 System.out.println("后置通知"); 13 } 14 public Object around(ProceedingJoinPoint pjp) throws Throwable{ 15 System.out.println("环绕前通知"); 16 Object value = pjp.proceed(); 17 System.out.println("环绕后通知"); 18 return value; 19 } 20 public void afterthrowing(JoinPoint jp,Throwable ex){ 21 //有异常时才输出 22 System.out.println("异常抛出通知"+ex); 23 } 24 public void after(JoinPoint jp){ 25 System.out.println("拦截目标方法名"+jp.getSignature().getName()); 26 System.out.println("最终通知"); 27 } 28 }
3.1在Spring的applicationContext.xml配置:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 7 <import resource="./aop4.xml" /> 8 </beans>
3.2在Spring的xmp配置apo1.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 10 <!-- target 目标对象 --> 11 <bean id="userService" class="cn.aspectjs.UserServiceImpl"/> 12 <!-- advice 通知--> 13 <bean id="userServiceAdvice" class="cn.aspectjs.UserServiceHelper"/> 14 <!-- config是用来声明,内容表示不管有没有接口,都用aspectj框架实现aop,aspect用来配置切面 --> 15 <aop:config proxy-target-class="true"> 16 <aop:aspect ref="userServiceAdvice"> 17 <aop:pointcut expression="execution(* *.add(..))" id="MypointCut"/> 18 <!-- method是增强类 --> 19 <aop:before method=""/> 20 <aop:before method="before" pointcut-ref="MypointCut"/> 21 <aop:after-returning method="afterreturning" pointcut-ref="MypointCut" returning="val"/> 22 <aop:around method="around" pointcut-ref="MypointCut" /> 23 <aop:after-throwing method="afterthrowing" pointcut-ref="MypointCut" throwing="ex"/> 24 <aop:after method="after" pointcut-ref="MypointCut" /> 25 </aop:aspect> 26 </aop:config> 27 </beans>
4.测试类
//Spring整合JUnit测试
@RunWith(SpringJUnit4ClassRunner.class)
//参数定义了要装入的Spring配置文件 2 @ContextConfiguration(locations="classpath:applicationContext.xml") 3 public class AspectJTest{ 4 @Autowired 5 private IUserService userService; 6 @Test 7 public void test1(){ 8 //对应aop1.xml中的aspectj定义的通知. 9 userService.add(); 10 } 11 }
基于annotation方案
1.编写目标
@Component //spring 扫描对象 public interface ICustomerService { public void save(); public void search(); public void update(); }
1 @Service 2 public class CustomerService implements ICustomerService { 3 @Override 4 public void save() { 5 System.out.println("save......"); 6 } 7 @Override 8 public void search() { 9 //System.out.println(10/0); 10 System.out.println("search......"); 11 } 12 @Override 13 public void update() { 14 System.out.println("update......"); 15 } 16 17 }
2.编写增强
1 //增强类(通知) 2 @Component//声明Spring容器 3 @Aspect//声明当前的bean的就是一个切面 4 public class CustomerServiceHelper { 5 @Pointcut("execution(* *.s*(..))") 6 private void mypointcut(){}; 7 8 @Pointcut("execution(* *.update(..))") 9 private void mypointcut1(){}; 10 //前置通知 11 @Before("mypointcut()||mypointcut1()") 12 public void beforeA(JoinPoint jp){ 13 System.out.println("目标类名称"+jp.getSignature().getDeclaringTypeName());
System.out.println("目标方法名称"+jp.getSignature().getName()); 14 System.out.println("前置通知......"); 15 } 16 @AfterReturning(value="execution(* *.s*(..))",returning="o") 17 public void AfterReturning(JoinPoint jp,Object o){ 18 System.out.println("后置通知.,目标方法的返回是"+o); 19 } 20 @Around("execution(* *.s*(..))") 21 public Object Around(ProceedingJoinPoint pjp) throws Throwable{ 22 System.out.println("执行前操作..."); 23 //是否执行目标方法 24 Object value = pjp.proceed(); 25 System.out.println("执行后操作..."); 26 //环绕通知必须要有返回值,值为目标方法的返回值 27 System.out.println("目标方法的返回值"+value); 28 return value; 29 } 30 @AfterThrowing (value="execution(* *.s*(..))",throwing="t") 31 public void AfterThrowing(JoinPoint jp,Throwable t){ 32 System.out.println("异常抛出通知......"+t); 33 } 34 @org.aspectj.lang.annotation.After(value="execution(* *.s*(..))") 35 public void After(JoinPoint jp){ 36 System.out.println("最后通知......"); 37 } 38 }
3.配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 10 <import resource="./aop2.xml"/> 11 </beans>
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 10 <!-- 在Spring配置文件中配置扫描注解 --> 11 <context:component-scan base-package="cn.annotation"/> 12 <!-- 开启aspectj注解自动代理 .false代表的是如果目标是有接口的使用proxy代理,如果没有接口使用cglib动态代理--> 13 <aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="false"/> 14 </beans>
4.测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:applicationContext.xml") public class AnnotationTest { @Autowired private ICustomerService customerService; @Test public void test(){ customerService.search(); } }
5.控制台打印结果
执行前操作...
目标类名称cn.annotation.CustomerService
目标方法名称search
前置通知......
search......
执行后操作...
执行通知,目标方法的返回值null
最后通知......
后置通知.,目标方法的返回是null