Spring AOP 使用注解定义切面(转载)

原文地址:http://www.jianshu.com/p/6f40dddd71a5

1.定义切面

下面我们就来定义一场舞台剧中观众的切面类Audience:

package com.spring.aop.service.aop;

import org.aspectj.lang.ProceedingJoinPoint;

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;

/**

* <dl>

* <dd>Description:观看演出的切面</dd>

* <dd>Company: 黑科技</dd>

* <dd>@date:2016年9月3日
下午9:58:09</dd>

* <dd>@author:Kong</dd>

* </dl>

*/

@Aspect

public
class
Audience {

/**

* 目标方法执行之前调用

*/

@Before("execution(** com.spring.aop.service.perform(..))")

public
void
silenceCellPhone() {

System.out.println("Silencing cell phones");

}

/**

* 目标方法执行之前调用

*/

@Before("execution(** com.spring.aop.service.perform(..))")

public
void
takeSeats() {

System.out.println("Taking seats");

}

/**

* 目标方法执行完后调用

*/

@AfterReturning("execution(** com.spring.aop.service.perform(..))")

public
void
applause() {

System.out.println("CLAP CLAP CLAP");

}

/**

* 目标方法发生异常时调用

*/

@AfterThrowing("execution(** com.spring.aop.service.perform(..))")

public
void
demandRefund() {

System.out.println("Demanding a refund");

}

}

我们可以看到使用了几种注解,其实AspectJ提供了五中注解来定义通知:


注解


通知


@After


通知方法会在目标方法返回或抛出异常后调用


@AfterRetruening


通常方法会在目标方法返回后调用


@AfterThrowing


通知方法会在目标方法抛出异常后调用


@Around


通知方法将目标方法封装起来


@Before


通知方法会在目标方法执行之前执行

  聪明的你可能已经看到,同样的切点我们写了四遍,这是不科学的,强大的Spring怎么会没有处理的方法呢。其实我们可以使用@Pointcut注解声明一个通用的切点,在后面可以随意使用:

package com.spring.aop.service.aop;

import org.aspectj.lang.ProceedingJoinPoint;

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;

/**

* <dl>

* <dd>Description:观看演出的切面</dd>

* <dd>Company: 黑科技</dd>

* <dd>@date:2016年9月3日
下午9:58:09</dd>

* <dd>@author:Kong</dd>

* </dl>

*/

@Aspect

public
class
Audience {

/**

* 定义一个公共的切点

*/

@Pointcut("execution(** com.spring.aop.service.Perfomance.perform(..))")

public void performance() {

}

/**

* 目标方法执行之前调用

*/

@Before("performance()")

public void silenceCellPhone() {

System.out.println("Silencing cell phones");

}

/**

* 目标方法执行之前调用

*/

@Before("performance()")

public void takeSeats() {

System.out.println("Taking seats");

}

/**

* 目标方法执行完后调用

*/

@AfterReturning("performance()")

public void applause() {

System.out.println("CLAP CLAP CLAP");

}

/**

* 目标方法发生异常时调用

*/

@AfterThrowing("performance()")

public void demandRefund() {

System.out.println("Demanding a refund");

}

}

  这样定义一个切点后,后面我们的方法想使用这个切点直接调用切点所在的方法就行了。实际上切面也是一个Java类,我们可以将它装配到Spring中的bean中:

/**

* 声明Audience bean

* @return

*/

@Bean

public Audience audience(){

return
new Audience();

}

  但是现在Spring还不会将Audience视为一个切面,即便使用了@AspectJ注解,但它并不会被视为一个切面们这些注解不会被解析,也不会创建将其转化为切面的代理。但我们可以使用JavaConfig,然后在JavaConfig类上使用注解@EnableAspectJAutoProxy注解启动自动代理功能:

package com.spring.aop.config;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

import com.spring.aop.service.aop.Audience;

/**

* <dl>

* <dd>Description:配置类</dd>

* <dd>Company: 黑科技</dd>

* <dd>@date:2016年9月3日
下午10:20:11</dd>

* <dd>@author:Kong</dd>

* </dl>

*/

@Configuration

//启动AspectJ自动代理

@EnableAspectJAutoProxy

@ComponentScan

public class ConcertConfig {

/**

* 声明Audience bean

* @return

*/

@Bean

public Audience audience(){

return new Audience();

}

}

如果你想使用XML配置也是可以的,我们要使用Spring aop命名空间中的<aop:aspectj-autoproxy>元素:

<?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:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"

xmlns:aop="http://www.springframework.org/schema/aop"

xmlns:cache="http://www.springframework.org/schema/cache"

xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd

http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd

http://www.springframework.org/schema/cache

http://www.springframework.org/schema/cache/spring-cache.xsd

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd

http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

<context:component-scan base-package="com.spring.aop" />

<!-- 启动AspectJ自动代理 -->

<aop:aspectj-autoproxy/>

<bean class="com.spring.aop.Audience" />

</beans>

  其实不管使用JAvaConfig还是Xml,AspectJ都会为使用@ApsectJ注解的Bean创建一个代理,这个代理会环绕着所有该切面所匹配的bean。

时间: 2025-01-19 23:32:49

Spring AOP 使用注解定义切面(转载)的相关文章

利用Spring AOP自定义注解解决日志和签名校验

转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!

spring AOP + 自定义注解实现权限控制小例子

今天看了一下黑马程序员的视频,上面讲到一个使用spring AOP + 自定义注解的方式来实现权限控制的一个小例子,个人觉得还是可以借鉴,整理出来与大家分享. 需求:service层有一些方法,这些方法需要不同的权限才能访问. 实现方案:自定义一个PrivilegeInfo的注解,使用这个注解为service层中的方法进行权限配置,在aop中根据PrivilegeInfo注解的值,判断用户是否拥有访问目标方法的权限,有则访问目标方法,没有则给出提示. 关键技术:自定义注解及注解解析,spring

Spring AOP基于注解的“零配置”方式

Spring AOP基于注解的“零配置”方式: Spring的beans.xml中 <!-- 指定自动搜索Bean组件.自动搜索切面类 --> <context:component-scan base-package="org.crazyit.app.service,org.crazyit.app.aspect"> <context:include-filter type="annotation" expression="or

(转)利用Spring AOP自定义注解解决日志和签名校验

一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: boolean isValid = accountService.validSignature(appid, signature, client_signature); if (!isValid) return ErrorUtil.buildError(ErrorUtil.ERR_CODE_COM

spring AOP自定义注解方式实现日志管理

转:spring AOP自定义注解方式实现日志管理 今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在applicationContext-mvc.xml中要添加的 <mvc:annotation-driven />     <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 -->     <conte

spring AOP自定义注解 实现日志管理

今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在applicationContext-mvc.xml中要添加的 <mvc:annotation-driven />     <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 -->     <context:component-scan base-pac

基于注解的Spring AOP的配置和使用--转载

AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向切面编程.可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现. 我们现在做的一些非业务,如:日志.事务.安全等都会写在业务代码中(也即是说,这些非业务类横切于业务类),但这些代码往往是重复,复制--粘贴式的代码会给程序的维护带来不便,AOP

Spring AOP基于注解的“零配置”方式实现

为了在Spring中启动@AspectJ支持,需要在类加载路径下新增两个AspectJ库:aspectjweaver.jar和aspectjrt.jar.除此之外,Spring AOP还需要依赖一个aopalliance.jar包 定义一个类似ServiceAspect.java这样的切面bean: 1 package com.hyq.aop; 2 3 import org.apache.commons.logging.Log; 4 import org.apache.commons.loggi

spring aop 日志 注解

前提:接上篇:spring aop 日志 一:无新增依赖包 二:修改切面类(aop.Log4jHandlerAOP.java) 三:修改applicationContext.xml 1:扫描注入容器新增aop(base-package="dao,service,aop") 2:支持AOP注解(<aop:aspectj-autoproxy/>) 3:去除传统AOP的配置以及切面类的注入 ps: 1:applicationContext.xml <?xml version