Spring之—— AspectJ AOP 完整示例
2015-11-09 20:58
579 查看
转载请注明出处:/article/8380942.html
这里我们用一个完整的例子演示spring aspectj aop的使用。
首先新建一个maven项目,在项目的pom.xml中添加spring aop相关的依赖项:
在maven中我们引入了spring aop相关的依赖,aspectj相关的包有两个,cglib是必须的。
下面我们在项目中新建一个Service类PersonService,它是业务代码,是我们AOP注入的目标类:
PersonService类中定义了三个方法,addPerson方法无返回值,而deletePerson方法有返回值,而editPerson方法抛出运行时的异常。
下面我们看Aspect类:
SimpleAspect类中的第一个方法是pointCut()方法,此方法无任何执行内容,只有一个@Pointcut的注解,其他方法都会引用这个注解中指定的pointcut表达式。
其他几个方法是各种Advice类型的方法实现,在这些方法中都可以通过JoinPoint实例来获得方法执行的上下文信息,参数信息。需要注意AfterReturning和AfterThrowing,After三种不同Advice的执行顺序。
有了spring框架和aspectj以及cglib的支持,我们只需要实现上面两个类就可以使用spring aop的功能了,下面我们看下如何在spring的配置文件中配置spring aop。
注意在beans节点中需要指定aop命名空间,一家chemaLocation地址,启用aop只需要添加
最后我们要测试下aop的效果,需要新建一个App类作为程序的入口类。
这个类中我们初始化了ApplicationContext,然后从中得到PersonService的实例,并执行其addPerson,deletePerson,editPerson方法,最后关闭ApplicationContext。
其执行结果如下:
这里我们用一个完整的例子演示spring aspectj aop的使用。
首先新建一个maven项目,在项目的pom.xml中添加spring aop相关的依赖项:
<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.outofmemory</groupId> <artifactId>spring-aop-aspect</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-aop-aspect</name> <url>http://maven.apache.org</url> <properties> <spring.version>3.1.1.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.12</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.6.12</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency> </dependencies> </project>
在maven中我们引入了spring aop相关的依赖,aspectj相关的包有两个,cglib是必须的。
下面我们在项目中新建一个Service类PersonService,它是业务代码,是我们AOP注入的目标类:
package cn.outofmemory.spring_aop_aspect; import org.springframework.stereotype.Service; @Service public class PersonService { public void addPerson(String personName) { System.out.println("add person " + personName); } public boolean deletePerson(String personName) { System.out.println("delete person " + personName) ; return true; } public void editPerson(String personName) { System.out.println("edit person " + personName); throw new RuntimeException("edit person throw exception"); } }
PersonService类中定义了三个方法,addPerson方法无返回值,而deletePerson方法有返回值,而editPerson方法抛出运行时的异常。
下面我们看Aspect类:
package cn.outofmemory.spring_aop_aspect; 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; @Component @Aspect public class SimpleAspect { @Pointcut("execution(* cn.outofmemory.spring_aop_aspect.*Service*.*(..))") public void pointCut() { } @After("pointCut()") public void after(JoinPoint joinPoint) { System.out.println("after aspect executed"); } @Before("pointCut()") public void before(JoinPoint joinPoint) { //如果需要这里可以取出参数进行处理 //Object[] args = joinPoint.getArgs(); System.out.println("before aspect executing"); } @AfterReturning(pointcut = "pointCut()", returning = "returnVal") public void afterReturning(JoinPoint joinPoint, Object returnVal) { System.out.println("afterReturning executed, return result is " + returnVal); } @Around("pointCut()") public void around(ProceedingJoinPoint pjp) throws Throwable { System.out.println("around start.."); try { pjp.proceed(); } catch (Throwable ex) { System.out.println("error in around"); throw ex; } System.out.println("around end"); } @AfterThrowing(pointcut = "pointCut()", throwing = "error") public void afterThrowing(JoinPoint jp, Throwable error) { System.out.println("error:" + error); } }
SimpleAspect类中的第一个方法是pointCut()方法,此方法无任何执行内容,只有一个@Pointcut的注解,其他方法都会引用这个注解中指定的pointcut表达式。
其他几个方法是各种Advice类型的方法实现,在这些方法中都可以通过JoinPoint实例来获得方法执行的上下文信息,参数信息。需要注意AfterReturning和AfterThrowing,After三种不同Advice的执行顺序。
有了spring框架和aspectj以及cglib的支持,我们只需要实现上面两个类就可以使用spring aop的功能了,下面我们看下如何在spring的配置文件中配置spring aop。
<?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-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <aop:aspectj-autoproxy /> <context:component-scan base-package="cn.outofmemory" /> </beans>
注意在beans节点中需要指定aop命名空间,一家chemaLocation地址,启用aop只需要添加
<aop:aspectj-autoproxy/>就可以了。<context:component-scan/>节点用来指定自动扫描bean的命名空间。
最后我们要测试下aop的效果,需要新建一个App类作为程序的入口类。
package cn.outofmemory.spring_aop_aspect; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Hello world! * */ public class App { public static void main( String[] args ) { ApplicationContext appContext = new ClassPathXmlApplicationContext("/appContext.xml"); PersonService personService = appContext.getBean(PersonService.class); String personName = "Jim"; personService.addPerson(personName); personService.deletePerson(personName); personService.editPerson(personName); ((ClassPathXmlApplicationContext)appContext).close(); } }
这个类中我们初始化了ApplicationContext,然后从中得到PersonService的实例,并执行其addPerson,deletePerson,editPerson方法,最后关闭ApplicationContext。
其执行结果如下:
before aspect executing around start.. add person Jim after aspect executed around end afterReturning executed, return result is null ------------------------------------- before aspect executing around start.. delete person Jim after aspect executed around end afterReturning executed, return result is null ---------------------------------------- before aspect executing around start.. edit person Jim after aspect executed error in around error:java.lang.RuntimeException: edit person throw exception Exception in thread ...从上面执行结果可以看到我们要执行的Before,around,after以及around,afterReturning,afterThrowing都正常的执行了。
相关文章推荐
- ASP.NET的几个试题(《C#与.NET程序员面试宝典》)
- ASP.NET多文件上传实例
- C#,Dictionary,asp.net 字典 用法及简单操作
- C#,Dictionary,asp.net 字典 用法及简单操作
- asp.net堆和栈的对比 #1
- asp.net试题解析
- Barcode Professional for ASP.NET使用教程:如何在HTML支持的DPI范围内显示高清条码
- Asp.Net 之 未能加载文件或程序集 system.web.extensions 解决方法
- Barcode Professional for ASP.NET使用教程:如何在HTML支持的DPI范围内显示高清条码
- ASP.NET中在不同的子域中共享Session(二级域名获取不到主域名下的session值)
- ASP.NET动态网站制作(26)-- Ajax
- ExtAspNet框架
- asp.net验证码及怎么获取里面的数值(整合)
- ASP.NET动态网站制作(25)-- ADO.NET(4)
- 转asp.net mvc 显示列表数据
- ASP.NET网址
- ASP.NET加载更多
- ASP.NET 连接mysql数据库
- asp.net中用FileStream类实现下载文件功能,自定义下载路径,像IE下载一样
- asp.net mvc4中自定义404页面