收藏私塾在线
 

欢迎您来到私塾在线网!   

请登录! 

免费注册 


zhang的笔记
状态: 离线
人气:5106301
访问用户量:4228
笔记经验:
总积分:261656
级别:VIP5
搜索本笔记
ta的交流分类
ta的交流主题贴(544)
ta的所有交流贴(1049)
ta的全部笔记
全部笔记(255)
未分类笔记(1)
Java Web(9)
并发实践(1)
课程问题(0)
Java(22)
架构(1)
缓存(5)
JavaEE(0)
JVM(12)
跟我学spring3(68)
Spring Sec……(43)
Spring 3.x……(25)
Spring Sec……(20)
跟开涛学Spring……(17)
深入剖析Spring……(18)
性能调优(10)
前端(2)
Tomcat源码解读(1)
spring sec……(0)
存档
2014-01(7)
2013-12(10)
2012-10(4)
2012-09(2)
2012-08(31)
2012-07(10)
2012-06(5)
2012-05(41)
2012-04(3)
2012-03(41)
2012-02(54)
2011-11(17)
2011-10(30)

2015-03-03 18:04:45
【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我学spring3
浏览(44474)|评论(5)   交流分类:Java|笔记分类: 跟我学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

精品视频课程推荐

透彻理解JavaBean视频教程
深入浅出的讲解JavaBen的写法、JavaBean的用法、JavaBean的实现机制、JavaBean对应翻译的代码理解。

深入浅出学Shrio视频教程
内容概述:Shiro是目前最热门、最易用、功能超强大的Java权限管理框架,强烈推荐,每个项目都必备的权限管理技术!通过本课程,你将从零开始直到彻底掌握Shiro的相关开发知识,达到可以进行实际项目开发的能力。包括:权限管理基础、Shiro入门、配置、身份认证、授权、Realms、Session管理、和Spring的集成、Web、Cache等众多开发细节技术 技术要点:源码级分析Shiro的授权过程、自定义开发Realm、多个Realms的开发配置、自定义开发AuthenticationStrategy、自定义开发自定义SessionDAO、和Struts2+Spring3的集成(包括修正struts2的bug)、Shiro和SpringMVC+Spring3的集成、包装使用其他的Cache框架、缓存数据同步更新的解决方案等等实际开发中常用的内容

研磨设计模式——跟着cc学设计系列视频教程
本视频课程是北京Java私塾原创精品书籍《研磨设计模式》一书的配套学习视频,由《研磨设计模式》的第一作者CC录制 课程目标:全面、系统的掌握GoF设计模式的知识,达到可以在实际项目开发中运用的能力 技术要点:如何实现可配置、如何实现缓存以及缓存的管理、如何实现用缓存来控制多实例的创建、如何实现参数化工厂、 如何实现可扩展工厂、如何实现原型管理器、如何实现Java的静态代理和动态代理、如何实现多线程处理队列请求、 如何实现命令的参数化配置、可撤销的操作、宏命令、队列请求和日志请求、如何实现翻页迭代、如何检测环状结构、 如何实现通用的增删改查、如何模拟工作流来处理流程、如何实现简单又通用的XML读取、如何实现模拟AOP的功能......

高级软件架构师实战培训阶段一
内容概述:本课程专注于构建:高可扩展性、高性能、大数据量、高并发、分布式的系统架构。 从零开始、全面系统、成体系的软件架构课程,循序渐进的讲述构建上述系统架构所需要的各种技术知识和技能。
技术要点: 1:构建基本的业务功能块,基于Maven+Git+Spring mvc+spring+mybatis+ehcache+mysql+X-gen代码生成
 2:高扩展性的分布式体系架构(基于Nginx+Varnish+Memcache+ActiveMQ)
 3:NoSQL的合理使用和架构优化(基于MongoDB)
 4:分布式文件存储和架构优化(基于MogileFS)

深入浅出学Spring Data JPA视频教程
系统、完整的学习Spring Data JPA开发的知识。包括:Spring Data JPA入门;JpaRepository基本功能 ;JpaRepository的查询;客户化扩展JpaRepository;Specifications查询。

浏览(44474)|评论(5)   交流分类:Java|笔记分类: 跟我学spring3

评论(5)
5楼 liuxiyangyang  2015-03-03 引用

博主,您好,您写的

3、定义切入点:

 

java代码:
  1. @Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")  
  2. public void beforePointcut(String param) {}  
这里的 目标方法不应该是sayAdvisorBefore,而应该是sayBefore吧,否则运行不出您给的如下结果:

将输出:

 

 
 

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

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

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

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

4楼 liuxiyangyang  2015-03-03 引用
博主,您好,您写的:
**************************************************************************************************
3、定义切入点:

java代码:
查看复制到剪贴板打印
@Pointcut(value="execution(* cn.javass..*.sayAdvisorBefore(..)) && args(param)", argNames = "param")
public void beforePointcut(String param) {}
**************************************************************************************************

目标方法不应该是sayAdvisorBefore,而应该是sayBefore吧?否则不会出现您给出的如下结果
将输出:



==========================================
===========before advice param:before
============say before
==========================================
3楼 liuxiyangyang  2015-03-03 引用

发表

2楼 zhang  2012-03-21 引用

 

w747351274写

aspectj比schema方式似乎简单,对吧,张老师

 

看场景

 

比如事务 schema方式简单

1楼 江磊  2012-03-21 引用

aspectj比schema方式似乎简单,对吧,张老师

请登录后评论 登录

关于我们 | 联系我们 | 用户协议 | 私塾在线服务协议 | 版权声明 | 隐私保护

版权所有 Copyright(C)2009-2012 私塾在线学习网