`
maakey
  • 浏览: 17114 次
文章分类
社区版块
存档分类
最新评论

【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我学spring3

 
阅读更多

Spring除了支持Schema方式配置AOP,还支持注解方式:使用@AspectJ风格的切面声明。

6.4.1 启用对@AspectJ的支持

Spring默认不支持@AspectJ风格的切面声明,为了支持需要使用如下配置:


java代码:
<aop:aspectj-autoproxy/>


这样Spring就能发现@AspectJ风格的切面并且将切面应用到目标对象。

6.4.2 声明切面

@AspectJ风格的声明切面非常简单,使用@Aspect注解进行声明:


java代码:
@Aspect()
Public class Aspect{
……
}


然后将该切面在配置文件中声明为Bean后,Spring就能自动识别并进行AOP方面的配置:


java代码:
<bean id="aspect" class="……Aspect"/>


该切面就是一个POJO,可以在该切面中进行切入点及通知定义,接着往下看吧。

6.4.3 声明切入点

@AspectJ风格的命名切入点使用org.aspectj.lang.annotation包下的@Pointcut+方法(方法必须是返回void类型)实现。


java代码:
@Pointcut(value="切入点表达式", argNames = "参数名列表")
public void pointcutName(……) {}
 

value:指定切入点表达式;

argNames:指定命名切入点方法参数列表参数名字,可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。

pointcutName:切入点名字,可以使用该名字进行引用该切入点表达式。


java代码:
@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")
public void beforePointcut(String param) {}


定义了一个切入点,名字为“beforePointcut”,该切入点将匹配目标方法的第一个参数类型为通知方法实现中参数名为“param”的参数类型。

6.4.4 声明通知

@AspectJ风格的声明通知也支持5种通知类型:


一、前置通知:使用org.aspectj.lang.annotation 包下的@Before注解声明;


java代码:
@Before(value = "切入点表达式或命名切入点", argNames = "参数列表参数名")


value:指定切入点表达式或命名切入点;

argNames:与Schema方式配置中的同义。

接下来示例一下吧:

1、定义接口和实现,在此我们就使用Schema风格时的定义;

2、定义切面:


java代码:
package cn.javass.spring.chapter6.aop;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class HelloWorldAspect2 {
 
}


3、定义切入点:


java代码:
@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")
public void beforePointcut(String param) {}


4、定义通知:


java代码:
@Before(value = "beforePointcut(param)", argNames = "param")
public void beforeAdvice(String param) {
    System.out.println("===========before advice param:" + param);
}


5、在chapter6/advice2.xml配置文件中进行如下配置:


java代码:
<?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"
        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">
          
  <aop:aspectj-autoproxy/>
  <bean id="helloWorldService"
            class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>
 
  <bean id="aspect"
             class="cn.javass.spring.chapter6.aop.HelloWorldAspect2"/>
 
</beans>
 


6、测试代码cn.javass.spring.chapter6.AopTest:


java代码:
@Test
public void testAnnotationBeforeAdvice() {
    System.out.println("======================================");
    ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter6/advice2.xml");
    IHelloWorldService helloworldService = ctx.getBean("helloWorldService", IHelloWorldService.class);
    helloworldService.sayBefore("before");
    System.out.println("======================================");
}



将输出:




==========================================

===========before advice param:before

============say before

==========================================










切面、切入点、通知全部使用注解完成:

1)使用@Aspect将POJO声明为切面;

2)使用@Pointcut进行命名切入点声明,同时指定目标方法第一个参数类型必须是java.lang.String,对于其他匹配的方法但参数类型不一致的将也是不匹配的,通过argNames = "param"指定了将把该匹配的目标方法参数传递给通知同名的参数上;

3)使用@Before进行前置通知声明,其中value用于定义切入点表达式或引用命名切入点;

4)配置文件需要使用<aop:aspectj-autoproxy/>来开启注解风格的@AspectJ支持;

5)需要将切面注册为Bean,如“aspect”Bean;

6)测试代码完全一样。



二、后置返回通知:使用org.aspectj.lang.annotation 包下的@AfterReturning注解声明;


java代码:
@AfterReturning(
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
returning="返回值对应参数名")

value:指定切入点表达式或命名切入点;

pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;

argNames:与Schema方式配置中的同义;

returning:与Schema方式配置中的同义。



java代码:
@AfterReturning(
    value="execution(* cn.javass..*.sayBefore(..))",
    pointcut="execution(* cn.javass..*.sayAfterReturning(..))",
    argNames="retVal", returning="retVal")
public void afterReturningAdvice(Object retVal) {
    System.out.println("===========after returning advice retVal:" + retVal);
}


其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationAfterReturningAdvice测试方法。

三、后置异常通知:使用org.aspectj.lang.annotation 包下的@AfterThrowing注解声明;


java代码:
@AfterThrowing (
value="切入点表达式或命名切入点",
pointcut="切入点表达式或命名切入点",
argNames="参数列表参数名",
throwing="异常对应参数名")
 


value:指定切入点表达式或命名切入点;

pointcut:同样是指定切入点表达式或命名切入点,如果指定了将覆盖value属性指定的,pointcut具有高优先级;

argNames:与Schema方式配置中的同义;

throwing:与Schema方式配置中的同义。



java代码:
@AfterThrowing(
    value="execution(* cn.javass..*.sayAfterThrowing(..))",
    argNames="exception", throwing="exception")
public void afterThrowingAdvice(Exception exception) {
    System.out.println("===========after throwing advice exception:" + exception);
}


其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationAfterThrowingAdvice测试方法。


四、后置最终通知:使用org.aspectj.lang.annotation 包下的@After注解声明;


java代码:
@After (
value="切入点表达式或命名切入点",
argNames="参数列表参数名")

value:指定切入点表达式或命名切入点;

argNames:与Schema方式配置中的同义;



java代码:
@After(value="execution(* cn.javass..*.sayAfterFinally(..))")
public void afterFinallyAdvice() {
    System.out.println("===========after finally advice");
}


其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationAfterFinallyAdvice测试方法。



五、环绕通知:使用org.aspectj.lang.annotation 包下的@Around注解声明;


java代码:
@Around (
value="切入点表达式或命名切入点",
argNames="参数列表参数名")


value:指定切入点表达式或命名切入点;

argNames:与Schema方式配置中的同义;



java代码:
@Around(value="execution(* cn.javass..*.sayAround(..))")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("===========around before advice");
    Object retVal = pjp.proceed(new Object[] {"replace"});
    System.out.println("===========around after advice");
    return retVal;
}



其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的annotationAroundAdviceTest测试方法。

6.4.5 引入

@AspectJ风格的引入声明在切面中使用org.aspectj.lang.annotation包下的@DeclareParents声明:


java代码:
@DeclareParents(
value=" AspectJ语法类型表达式",
defaultImpl=引入接口的默认实现类)
private Interface interface;


value:匹配需要引入接口的目标对象的AspectJ语法类型表达式;与Schema方式中的types-matching属性同义;

private Interface interface指定需要引入的接口;

defaultImpl指定引入接口的默认实现类,没有与Schema方式中的delegate-ref属性同义的定义方式;


java代码:
@DeclareParents(
    value="cn.javass..*.IHelloWorldService+", defaultImpl=cn.javass.spring.chapter6.service.impl.IntroductiondService.class)
private IIntroductionService introductionService;
 


其中测试代码与Schema方式几乎一样,在此就不演示了,如果需要请参考AopTest.java中的testAnnotationIntroduction测试方法。


原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/2471.html

分享到:
评论

相关推荐

    征服Spring AOP—— @AspectJ

    在IT行业中,Spring框架是Java企业级应用开发的首选,而Spring AOP(面向切面编程)则是其核心特性之一,用于实现横切关注点的模块化,如日志、事务管理等。@AspectJ是Spring AOP的一种注解驱动方式,它极大地简化了...

    Spring AOP 概念理解及@AspectJ支持

    **Spring AOP 概念理解** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的一个重要组成部分,它允许我们通过...理解和熟练运用Spring AOP及其@AspectJ注解是每个Spring开发者必备的技能之一。

    跟开涛学Spring

    1.22 【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我学spring3 . . . . . . . . . . . . . . . . . . . . . . .238 1.23 【第六章】 AOP 之 6.6 通知参数 ——跟我学spring3 . . . . . . . . . . . . . . . . ....

    @AspectJ配置Spring AOP,demo

    `基于@AspectJ配置Spring AOP之一 - 飞扬部落编程仓库-专注编程,网站,专业技术.htm`和其关联的`_files`目录可能包含了一个详细的教程或演示如何配置和运行@AspectJ的Spring AOP应用程序。 通过以上内容,我们可以...

    Spring的AOP实例(XML+@AspectJ双版本解析+源码+类库)

    **Spring的AOP实例——XML与@AspectJ双版本解析** Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来处理系统的交叉关注点,如日志、事务管理等。AOP的核心概念包括切面...

    spring AOP 实例(@AspectJ)

    一个基于@AspectJ的spring2.0 AOP应用实例,很小很简单,没有任何额外信息,最适合AOP入门学习。使用log4j打印信息。把项目直接import进myeclipse就可以使用啦......

    Spring AOP @AspectJ 入门实例

    在IT行业中,Spring框架是Java企业级应用开发的首选,而Spring AOP(面向切面编程)则是其核心特性之一,用于实现横切关注点的模块化,如日志、事务管理等。本实例将带你深入理解并实践Spring AOP与@AspectJ的结合...

    Spring @AspectJ 实现AOP 入门例子

    本篇文章将深入探讨如何利用Spring的@AspectJ注解来实现AOP,这是一个入门级别的例子,旨在帮助开发者理解并掌握这一关键特性。 首先,我们要明白什么是AOP。面向切面编程是一种编程范式,它允许程序员定义“切面”...

    spring对AOP的支持(使用AspectJ进行AOP演示)

    Spring 框架是 Java 开发中的重要组件,它提供了丰富的功能,其中之一就是对面向切面编程(AOP)的支持。面向切面编程是一种编程范式,旨在将关注点分离,使得业务逻辑与横切关注点(如日志、事务管理、安全检查等)...

    Spring 使用AspectJ 实现 AOP

    Spring 框架是Java开发中的一个核心组件,它提供了许多功能,其中之一就是面向切面编程(AOP)。AOP是一种编程范式,允许开发者将关注点从业务逻辑中分离出来,比如日志记录、事务管理等。在Spring中,我们可以使用...

    Spring 使用AspectJ 实现 AOP(基于xml文件、基于注解)

    本教程将探讨如何在Spring中结合AspectJ实现AOP,包括基于XML配置和基于注解的方式。 **一、AOP基本概念** AOP的核心概念有切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)和引入...

    AspectJ in Action: Enterprise AOP with Spring Applications

    ### AspectJ in Action: Enterprise AOP with Spring Applications #### 关键知识点概述 1. **Spring-AspectJ集成:**本书重点介绍了Spring框架与AspectJ相结合的技术优势及其在企业级应用中的强大功能。 2. **...

    Spring的AOP依赖包-AspectJ

    而AspectJ是Java平台上的一个开源项目,提供了一种强大的、类型安全的AOP解决方案,它能够与Spring框架完美结合,增强Spring的AOP功能。 首先,我们需要理解AOP的核心概念。切面(Aspect)是关注点的模块化,这些...

    跟我学spring

    标题“跟我学spring”和描述“spring 的使用,每个知识点和项目中的运用,20章的介绍。”暗示这是一份详细介绍Spring框架使用方法的教程或手册,覆盖了Spring的各个方面,并以实例为导向,深入探讨了每个知识点在...

    Spring AOP之基于AspectJ注解总结与案例

    本篇内容将对Spring AOP中基于AspectJ注解的使用进行总结,并通过实际案例进行解析。 首先,让我们理解AspectJ注解在Spring AOP中的核心概念: 1. **@Aspect**: 这个注解用于定义一个类为切面,这个类将包含切点和...

    跟我学spring3

    《跟我学Spring3》是一本深入浅出的Spring框架学习指南,主要针对Spring 3.x版本进行详细讲解。Spring作为Java领域最流行的轻量级框架,它的应用广泛且功能强大,涵盖依赖注入、AOP(面向切面编程)、数据访问、Web...

Global site tag (gtag.js) - Google Analytics