前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring-AOP之aspectj注解方式

Spring-AOP之aspectj注解方式

作者头像
java达人
发布2018-01-31 11:30:20
1.2K0
发布2018-01-31 11:30:20
举报
文章被收录于专栏:java达人java达人

一、简介 1、AOP用在哪些方面:AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理日志管理权限控制异常处理等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。 2、AOP中的概念: Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象. joinpoint(连接点):所谓连接点是指那些被拦截到的点(可以是方法、属性、或者类的初始化时机(可以是Action层、Service层、dao层))。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器) Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义,也即joinpoint的集合. Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知 Target(目标对象):代理的目标对象 Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入. Introduction(引入):在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field.

3、AOP带来的好处::降低模块的耦合度;使系统容易扩展;更好的代码复用性

二、通过注解方式实现Spring的AOP

1.定义业务类

接口:

[java]

代码语言:js
复制
package cn.slimsmart.spring.demo.aop;  
 
public interface UserService {  
    String save(String name);  
    String update(String name);  
    String delete(String name);  
}  

实现:

[java]

代码语言:js
复制
package cn.slimsmart.spring.demo.aop;  
 
import org.springframework.stereotype.Service;  
 
@Service  <span style="font-family: Arial, Helvetica, sans-serif;">//使用自动注解的方式实例化并初始化该类</span> 
public class UserServiceImpl implements UserService{  
 
 @Override 
 public String save(String name) {  
        System.out.println("--------save");  
 return "save";  
    }  
 
 @Override 
 public String update(String name) {  
        System.out.println("--------update");  
        System.out.println(1/0);  
 return "update";  
    }  
 
 @Override 
 public String delete(String name) {  
        System.out.println("--------delete");  
 return "delete";  
    }  
 
}  

2.定义切面类

[java]

代码语言:js
复制
package cn.slimsmart.spring.demo.aop;  
 
import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.After;  
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;  
 
//@Aspect : 标记为切面类 
//@Pointcut : 指定匹配切点集合 
//@Before : 指定前置通知,value中指定切入点匹配 
//@AfterReturning :后置通知,具有可以指定返回值 
//@AfterThrowing :异常通知 
//@Around 环绕通知 环绕通知的方法中一定要有ProceedingJoinPoint 参数,与Filter中的  doFilter方法类似 
//注意:前置/后置/异常通知的函数都没有返回值,只有环绕通知有返回值 
@Component //使用自动注解的方式实例化并初始化该类 
@Aspect 
public class TestInterceptor {  
 
 //如果要设置多个切点可以使用 || 拼接 
 @Pointcut("execution(* cn.slimsmart.spring.demo.aop.UserServiceImpl.*(..))")  
 private void anyMethod() {  
    }// 定义一个切入点 
 
 @Before(value="anyMethod()")  
 public void doBefore(JoinPoint joinPoint) {  
        System.out.println("前置通知");  
    }  
 
 @AfterReturning(value="anyMethod()",returning="result")  
 public void doAfter(JoinPoint jp, String result) {  
        System.out.println("后置通知");  
    }  
 
 @After("anyMethod()")  
 public void after() {  
        System.out.println("最终通知");  
    }  
 
 @AfterThrowing(value="execution(* cn.slimsmart.spring.demo.aop.*.*(..))",throwing="e")  
 public void doAfterThrow(JoinPoint joinPoint, Throwable e) {  
        System.out.println("异常通知");  
    }  
 
 @Around("execution(* cn.slimsmart.spring.demo.aop.*.*(..))")  
 public Object doBasicProfiling(ProceedingJoinPoint joinPoint) throws Throwable {  
        System.out.println("进入环绕通知");  
        System.out.println("目标类名称:"+joinPoint.getTarget().getClass().getName());  
        System.out.println("方法名称:"+joinPoint.getSignature().getName());  
        System.out.println("方法参数:"+joinPoint.getArgs());  
        System.out.println("staticPart:"+ joinPoint.getStaticPart().toShortString());  
        System.out.println("kind:"+joinPoint.getKind());  
        System.out.println("sourceLocation:"+joinPoint.getSourceLocation());  
        Object object = joinPoint.proceed();// 执行该方法 
        System.out.println("退出方法");  
 return object;  
    }  
 
}  

3.applicationContext.xml配置

[html]

代码语言:js
复制
<?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:context="http://www.springframework.org/schema/context" 
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xmlns:tx="http://www.springframework.org/schema/tx" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> 
 <context:component-scan base-package="cn.slimsmart.spring.demo" /> 
 <!-- 打开aop 注解 --> 
 <aop:aspectj-autoproxy proxy-target-class="true"/> 
 
</beans> 

4.单元测试类

[java]

代码语言:js
复制
package cn.slimsmart.spring.demo;  
 
import org.junit.Test;  
import org.junit.runner.RunWith;  
import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.test.context.ContextConfiguration;  
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;  
 
import cn.slimsmart.spring.demo.aop.UserService;  
 
@RunWith(SpringJUnit4ClassRunner.class)//让junit工作在spring环境中 
@ContextConfiguration(locations={"classpath:applicationContext.xml"})  
public class SpringTest{  
 
 @Autowired 
    UserService userService;  
 
 @Test 
 public void testStart(){  
        System.out.println("启动服务");  
        userService.delete("abc123");  
        System.out.println("====================");  
        userService.update("aaa");  
    }  
 
}  

运行结果:执行update抛异常:/ by zero

[plain]

  1. 启动服务
  2. 进入环绕通知
  3. 目标类名称:cn.slimsmart.spring.demo.aop.UserServiceImpl
  4. 方法名称:delete
  5. 方法参数:[Ljava.lang.Object;@2de1c3f9
  6. staticPart:execution(UserServiceImpl.delete(..))
  7. kind:method-execution
  8. sourceLocation:org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@6ed745c2
  9. 前置通知
  10. --------delete
  11. 退出方法
  12. 最终通知
  13. 后置通知
  14. ====================
  15. 进入环绕通知
  16. 目标类名称:cn.slimsmart.spring.demo.aop.UserServiceImpl
  17. 方法名称:update
  18. 方法参数:[Ljava.lang.Object;@1d370b4d
  19. staticPart:execution(UserServiceImpl.update(..))
  20. kind:method-execution
  21. sourceLocation:org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@8c6fb37
  22. 前置通知
  23. --------update
  24. 最终通知
  25. 异常通知

注:pom.xml引入的jar包

[html]

代码语言:js
复制
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
 <modelVersion>4.0.0</modelVersion> 
 <groupId>cn.slimsmart.spring.demo</groupId> 
 <artifactId>spring-demo</artifactId> 
 <version>0.0.1-SNAPSHOT</version> 
 <dependencies> 
 <dependency> 
 <groupId>org.springframework</groupId> 
 <artifactId>spring-context</artifactId> 
 <version>4.1.4.RELEASE</version> 
 </dependency> 
 <!-- <dependency> --> 
 <!-- <groupId>org.springframework</groupId> --> 
 <!-- <artifactId>spring-tx</artifactId> --> 
 <!-- <version>4.1.4.RELEASE</version> --> 
 <!-- </dependency> --> 
 <!-- <dependency> --> 
 <!-- <groupId>org.springframework</groupId> --> 
 <!-- <artifactId>spring-jdbc</artifactId> --> 
 <!-- <version>4.1.4.RELEASE</version> --> 
 <!-- </dependency> --> 
 <dependency> 
 <groupId>org.springframework</groupId> 
 <artifactId>spring-test</artifactId> 
 <version>4.1.4.RELEASE</version> 
 </dependency> 
 <dependency> 
 <groupId>aspectj</groupId> 
 <artifactId>aspectjrt</artifactId> 
 <version>1.5.4</version> 
 </dependency> 
 <dependency> 
 <groupId>org.aspectj</groupId> 
 <artifactId>aspectjweaver</artifactId> 
 <version>1.8.4</version> 
 </dependency> 
 
 <dependency> 
 <groupId>cglib</groupId> 
 <artifactId>cglib</artifactId> 
 <version>3.1</version> 
 </dependency> 
 <dependency> 
 <groupId>cglib</groupId> 
 <artifactId>cglib-nodep</artifactId> 
 <version>3.1</version> 
 </dependency> 
 <dependency> 
 <groupId>junit</groupId> 
 <artifactId>junit</artifactId> 
 <version>4.12</version> 
 </dependency> 
 
 </dependencies> 
</project> 

若不使用注解的方式,使用schema xml配置(也可以基于spring接口方式实现)的方式,如下参考:

[html]

代码语言:js
复制
<aop:config> 
 <aop:aspect id="businessAspect" ref="testInterceptor"> 
 <!-- 配置指定切入的对象 --> 
 <aop:pointcut id="point_cut" expression="execution(* cn.slimsmart.spring.demo.aop.UserServiceImpl.*(..))" /> 
 <!-- 前置通知 --> 
 <aop:before method="doBefore" pointcut-ref="point_cut" /> 
 <!-- 后置通知 returning指定返回参数 --> 
 <aop:after-returning method="doAfter" 
 pointcut-ref="point_cut" returning="result" /> 
 <aop:around method="doAround" pointcut-ref="point_cut"/> 
 <aop:after-throwing method="doThrow" pointcut-ref="point_cut" throwing="e"/> 
 </aop:aspect> 
 </aop:config> 
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2015-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java达人 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档