Spring基于注解@AspectJ的AOP

原创 2015年07月07日 08:55:59

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(……) {}  

声明通知

前置通知

使用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=====================
======================================


版权声明:本文为博主原创文章,未经博主允许不得转载。

Spring Aop实例之AspectJ注解配置

上篇博文《Spring Aop实例之xml配置》中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop。        依旧采用的jdk代理,接口和实现类代码请参考上...
  • xiaoxian8023
  • xiaoxian8023
  • 2013年12月26日 08:00
  • 37031

Spring AOP之AspectJ的注解方式使用

需要导入的jar包,请看上一篇博客。 注解: 如果使用注解进行aop开发,必须进行aspectj自动代理 通知注解 @Before 前置 ...
  • u010889616
  • u010889616
  • 2016年09月04日 22:22
  • 1857

Spring AOP(三)——通过@AspectJ注解切面

在Spring AOP(二)中给出了在XML中配置切面的方法,本节学习通过@AspectJ来注解切面,使用的例子仍然是Spring AOP(二)中的例子,前面讲的已经很详细了,具体原理不再说明,直接上...
  • Trigl
  • Trigl
  • 2016年03月17日 21:21
  • 3145

Sping AOP用AspectJ注解的方式拦截不到SpringMVC的controller方法?

为什么Sping AOP用AspectJ注解的方式拦截不到SpringMVC的controller方法,如何解决这个问题,本例将带你解决此问题。...
  • zzg1229059735
  • zzg1229059735
  • 2015年12月04日 16:04
  • 3127

Spring 之AOP AspectJ切入点语法详解

三6.5  AspectJ切入点语法详解 6.5.1  Spring AOP支持的AspectJ切入点指示符        切入点指示符用来指示切入点表达式目的,,在Spring AOP中目前...
  • Happy_wu
  • Happy_wu
  • 2016年07月27日 10:51
  • 1992

SpringAop与AspectJ的联系与区别

SpringAop与AspectJ的联系与区别区别AspectJAspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字...
  • qq_21050291
  • qq_21050291
  • 2017年05月19日 11:43
  • 1857

Spring AOP AspectJ注解和XML配置两种实现(Maven构建)

Spring AOP 的两种实现方式分别是注解@(基于AspectJ)和XML配置,虽然方式不同,但万变不离其宗,最终都是运用java反射和动态代理技术(这是JDK方式)或者java反射和CGlib(...
  • fyduan
  • fyduan
  • 2015年12月23日 19:04
  • 8949

Spring AOP支持的AspectJ语法详解

6.5  AspectJ切入点语法详解 6.5.1  Spring AOP支持的AspectJ切入点指示符        切入点指示符用来指示切入点表达式目的,,在Spring AOP中目...
  • etjnety
  • etjnety
  • 2013年04月10日 11:48
  • 4561

比较分析 Spring AOP 和 AspectJ 之间的差别

AOP(Aspect OrientedProgramming, 面向切面/方面编程) 旨在从业务逻辑中分离出来横切逻辑【eg:性能监控、日志记录、权限控制等】,提高模块化,即通过AOP解决代码耦合问题...
  • a128953ad
  • a128953ad
  • 2016年01月13日 18:02
  • 3246

10、SSM框架-Spring AOP之基于注解的声明式AspectJ(10)

spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明。导入需要的包:aspectjweaver.jar、aopalliance-1.0.jar 本文工程...
  • gywtzh0889
  • gywtzh0889
  • 2016年11月03日 12:58
  • 640
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring基于注解@AspectJ的AOP
举报原因:
原因补充:

(最多只允许输入30个字)