Spring基于注解@AspectJ的AOP
2015-07-07 08:55
711 查看
Spring除了支持XML方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明。
但是用注解方式需要在XML启用对@AspectJ的支持<aop:aspectj-autoproxy/>,将在Spring上下文创建一个AnnotationAwareAspectJAutoProxyCreator类,它会自动代理一些Bean,这些Bean的方法需要与使用@Aspect注解的Bena中所定义的切点相匹配,而这些切点又是使用@Pointcut注解定义出来的,下面来看下例子(PS:我的例子都没有携带参数):
@AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut方法(方法必须是返回void类型)实现。
@Pointcut(value="切入点表达式", argNames = "参数名列表")
public void pointcutName(……) {}
包下的@Before注解声明;
@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名")
包下的@AfterReturning注解声明;
@AfterReturning(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
returning="返回值对应参数名")
包下的@After注解声明;
@After (
value="切入点表达式或命名切入点",
argNames="参数列表参数名")
包下的@AfterThrowing注解声明
@AfterThrowing
(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
throwing="异常对应参数名")
运行测试方法控制台输出:
======================================
等候节目开始===
showBefore============
showEnd===============
鼓掌=========
======================================
@Around (
value="切入点表达式或命名切入点",
argNames="参数列表参数名")
======================================
around before advice===========
around===========around
around after advice===========
======================================
@DeclareParents(
value="AspectJ语法类型表达式",
defaultImpl="引入接口的默认实现类")
运行测试方法输出结果:
======================================
declare=====================
======================================
但是用注解方式需要在XML启用对@AspectJ的支持<aop:aspectj-autoproxy/>,将在Spring上下文创建一个AnnotationAwareAspectJAutoProxyCreator类,它会自动代理一些Bean,这些Bean的方法需要与使用@Aspect注解的Bena中所定义的切点相匹配,而这些切点又是使用@Pointcut注解定义出来的,下面来看下例子(PS:我的例子都没有携带参数):
声明切入点
@AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut方法(方法必须是返回void类型)实现。@Pointcut(value="切入点表达式", argNames = "参数名列表")
public void pointcutName(……) {}
声明通知
前置通知
使用org.aspectj.lang.annotation包下的@Before注解声明;
@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名")
后置返回通知
使用org.aspectj.lang.annotation包下的@AfterReturning注解声明;
@AfterReturning(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
returning="返回值对应参数名")
后置最终通知
使用org.aspectj.lang.annotation包下的@After注解声明;
@After (
value="切入点表达式或命名切入点",
argNames="参数列表参数名")
后置异常通知
使用org.aspectj.lang.annotation包下的@AfterThrowing注解声明
@AfterThrowing
(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
throwing="异常对应参数名")
package cn.com.ztz.spring.service; public interface ShowService { public void show(); }
package cn.com.ztz.spring.service; public class ShowServiceImpl implements ShowService{ @Override public void show() { showBefore(); //showError();//异常测试 (后置异常通知) showEnd(); } public void showBefore(){ System.out.println("showBefore============"); } public void showError(){ System.out.println("showError============"); throw new RuntimeException(); } public void showEnd(){ System.out.println("showEnd==============="); } }
package cn.com.ztz.spring.service; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class AudienceAspect { //定义切点 @Pointcut("execution(* cn.com.ztz.spring.service.ShowServiceImpl.show(..))") public void performance(){ //该方法的内容不重要,该方法的本身只是个标识,供@Pointcut注解依附 } //前置通知 @Before("performance()") public void taskSeats(){ System.out.println("等候节目开始==="); } //后置通知 @After("performance()") public void applaud(){ System.out.println("鼓掌========="); } //后置异常通知 @AfterThrowing("performance()") public void demandRefund(){ System.out.println("退钱离场======"); } }
<!-- 启用@AspectJ支持 --> <aop:aspectj-autoproxy/> <bean id="show" class="cn.com.ztz.spring.service.ShowServiceImpl"/> <bean id="audienceAspect" class="cn.com.ztz.spring.service.AudienceAspect"/>
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); ShowService hs = ctx.getBean("show", ShowService.class); System.out.println("======================================"); hs.show(); System.out.println("======================================"); }
运行测试方法控制台输出:
======================================
等候节目开始===
showBefore============
showEnd===============
鼓掌=========
======================================
注解环绕通知
像Spring基于XML的AOP一样,@AspectJ注解的使用不仅只限定与定义前置和后置通知类型。我们还可以创建环绕通知,使用环绕通知需要使用@Around。@Around (
value="切入点表达式或命名切入点",
argNames="参数列表参数名")
public interface ShowService { public void show(String param); }
@Override public void show(String param) { System.out.println("around==========="+param); }
@Aspect public class AudienceAspect { //定义切点 @Pointcut("execution(* cn.com.ztz.spring.service.ShowServiceImpl.show(..))") public void performance(){ //该方法的内容不重要,该方法的本身只是个标识,供@Pointcut注解依附 } @Around("performance()") public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable { System.out.println("around before advice==========="); Object retVal = pjp.proceed(new Object[] {"around"}); System.out.println("around after advice==========="); return retVal; } }运行测试方法控制台输出:
======================================
around before advice===========
around===========around
around after advice===========
======================================
引入
@AspectJ风格的引入声明在切面中使用org.aspectj.lang.annotation包下的@DeclareParents声明@DeclareParents(
value="AspectJ语法类型表达式",
defaultImpl="引入接口的默认实现类")
package cn.com.ztz.spring.service; public interface DeclareService { public void declare(); }
package cn.com.ztz.spring.service; public class DeclareServiceImpl implements DeclareService { @Override public void declare() { System.out.println("declare====================="); } }
package cn.com.ztz.spring.service; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.DeclareParents; @Aspect public class AudienceAspect { @DeclareParents(value="cn.com.ztz.spring.service.ShowServiceImpl+", defaultImpl=cn.com.ztz.spring.service.DeclareServiceImpl.class) private DeclareService declareService;}
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); DeclareService hs = ctx.getBean("show", DeclareService.class); System.out.println("======================================"); hs.declare(); System.out.println("======================================"); }
运行测试方法输出结果:
======================================
declare=====================
======================================
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao
- 读取spring配置文件的方法(spring读取资源文件)
- java实现简单美女拼图游戏
- java基本教程之线程休眠 java多线程教程
- JSP开发中在spring mvc项目中实现登录账号单浏览器登录
- 基于Spring框架的Shiro配置方法
- Spring MVC中上传文件实例
- 实例讲解Java的Spring框架中的AOP实现
- 解析Java中如何获取Spring中配置的bean
- Spring的注解配置与XML配置之间的比较
- java Spring整合Freemarker的详细步骤
- Java 二维码,QR码,J4L-QRCode 的资料整理
- java当中的定时器的4种使用方式
- java中 spring 定时任务 实现代码