spring配置aop的方式有哪些

spring配置aop的方式有哪些,第1张

在Spring中实现AOP根据版本不同,可以有大致四种配置方式。现简单列一下。在介绍Spring的AOP配置方式前,先要注意Spring中Advisor的概念。在Spring中Advisor是Advice和Pointcut的结合,但它还不是AOP概念上的Aspect。因为在Spring中Advisor还是Spring用来生成Aspect对象的一个原型,根据配置的不同,Spring可以只对某个类生成Aspect,也可以对所有的类生成Aspect。

1 基于xml配置文件的代理配置方式

这种方式在20以后很少用了,原因是配置项过多,过于繁琐。但对于理解Spring AOP还是很有帮助的

11 定义通知

<bean id="advice" class="yourAdviceImpl" />

12 定义切点

要定义一个切点,可以选择使用正则表达式方式声明的切点或者AspectJ方式声明的切点。对正则表达式切点,使用Perl5RegexpMethodPointcut或JdkRegexpMethodPointcut(Java

14以上版本,不需要Jakarta ORO的支持了);对AspectJ切点,使用AspectJExpressPointcut

<bean id="pointcut" class="orgspringframeworkaopsupportJdkRegexpMethodPointcut">

<property name="pattern" value="yourRegularExpression" />

</bean>

<bean id="pointcut" class="orgspringframeworkaopaspectjAspectJExpressionPointcut">

<property name="expression" value="yourAspectJExpression" />

</bean>

13 定义通知者

DefaultPointcutAdvisor是Spring提供的默认通知者,它需要提供通知和切点的引用。

Spring也提供了RegexpMethodPointcutAdvisor和AspectJExpressionPointcutAdvisor来对应两种声明切点的方式,不用再单独定义切点。

<bean id="advisor" class="orgspringframeworkaopsupportDefaultPointcutAdvisor">

<property name="advice" ref="advice" />

<property name="pointcut" ref="pointcut" />

</bean>

<bean id="advisor" class="orgspringframeworkaopsupportRegexpMethodPointcutAdvisor">

<property name="advice" ref="advice" />

<property name="pattern" value="yourRegularExpression" />

</bean>

<bean id="advisor" class="orgspringframeworkaopaspectjAspectJExpressionPointcut">

<property name="advice" ref="advice" />

<property name="expression" value="yourAspectjExpression" />

</bean>

14 定义ProxyFactoryBean

<bean id="yourBean" class="orgspringframeworkaopframeworkProxyFactoryBean>

<property name="target" ref="yourTargetBean" />

<property name="interceptorNames" value="advisor" />

<property name="proxyInterfaces" value="interfaceClass" />

</bean>

interceptorNames和proxyInterfaces都是数组属性,所以可以声明要使用的一个list,也可以让Spring自动把单个值转化为数组

上面明确定义了要对那个targetBean应用代理生成切面实例。如果不想限制targetBean,可以让Spring为所有匹配切点声明的bean生成切面实例,这样就不用一个个定义ProxyFactoryBean了,只需要定义

<bean class="orgspringframeworkaopframeworkautoproxyDefaultAdvisorAutoProxyCreator" />

这是一个BeanPostProcessor,所以Spring会自动识别并在bean的声明周期使用

2 利用20以后使用aop标签

<aop:config>

<aop:aspect ref="">

<aop:pointcut id="performance" expression="execution( perform())" />

<aop:before method="" pointcut-ref="performance" />

<aop:before method="" pointcut="execution( perform())" />

<aop:after-returning method="" pointcut="execution( perform())" />

<aop:after-throwing method="" pointcut="execution( perform())" />

</aop:aspect>

</aop:config>

3 利用Annotation

31 利用@Aspect将一个POJO类声明为一个切面。

32 定义切点

@Pointcut("execution( perform())")

public void performance(){}

通过@Pointcut定义的切点的名字就是它所注解的方法的名字,因此例子中的切点名字是

performance()。这里声明的performance()方法实际圣只是一个标记,为@Pointcut提供附加的点,并不要求有实际意义。

33 定义通知

对要执行切面的方法,通过@Before("performance()"),@AfterReturning

("performance()")来定义通知。注意这里提供的切点名称,是performance(),而不是performance

如果对上面的两点不是很理解,也可以省略@Pointcut,而将AspectJ表达式直接定义在@Before等通知中,将上面的两步合为一步,如@Before("execution( perform())")

34 通知Spring创建代理

<aop:aspectj-autoproxy>

这实际上相当于声明了一个AnnotationAwareAspectJAutoProxyCreator,从而根据@Pointcut声明的切点来自动代理匹配的bean实例

4 在Spring中结合进AspectJ

对于超出Spring AOP支持范围的,可以采用这种方式。只需要在Spring中配置AspectJ的Class实例时让Spring能够获得AspectJ类的实例就可以了,比如

<bean class="a_aspectj_class" factory-method="aspectOf">

<preperty />

</bean>

最近在项目有一个 *** 作时间监控功能

项目采用的是 spring31 mvc -control注解

为了对所有的 *** 作进行执行时间监控,编写了一个AOP

配置mvc aop的时候,刚开始按照普通的aspect注解的方式配置,无法生效。

后面查了相关的资料,有的说@control不支持AOP ,有的说支持,但笔者最后还是成功的找到了

相关的配置方法,因为笔者喜欢Aspect的注解风格。所以笔者只提供Aspect风格的相关配置。相关jar网上搜下。笔者只讲mvc 切面生效的配置。

前提条件MVC配置成功。

编写AOP类

package comwxaoptimer;

import orgapachelog4jLogger;

import orgaspectjlangProceedingJoinPoint;

import orgaspectjlangannotationAround;

import orgaspectjlangannotationAspect;

import orgspringframeworkstereotypeComponent;

@Component

@Aspect

public class Timer {

private Logger logger =LoggergetLogger(getClass());

//可以尝试下这两种注解

// @Around("execution( orgspringframeworkwebservletmvcannotationAnnotationMethodHandlerAdapterhandle())")

@Around("@annotation(orgspringframeworkwebbindannotationRequestMapping)")

public Object logTimer(ProceedingJoinPoint thisJoinPoint) throws Throwable {

String clazzName = thisJoinPointgetTarget()getClass()getName();

String methodName = thisJoinPointgetSignature()getName();

// 计时并调用目标函数

long start = SystemcurrentTimeMillis();

Object result = thisJoinPointproceed();

long time = SystemcurrentTimeMillis() - start;

// 输出计时信息

loggerinfo(" *** 作计时:" + time + "ms 类名: " + clazzName+ " 方法名:" + methodName + "()");

return result;

}

}

spring-servlet配置文件加入下面配置语句:

<aop:aspectj-autoproxy proxy-target-class="true" /> <!-- aspect注解生效-->

<!-- aop切面 -->

<bean id="timer" class="comwxaoptimerTimer" />

笔者mvc配置文件为spring-servletxml整个配置文件如下:

<xml version="10" encoding="UTF-8">

<beans xmlns=">

有配置的,代码示例如下:

这是业务测试类:

package aopannotationservice;

import orgspringframeworkcontextannotationScope;

import orgspringframeworkstereotypeService;

@Service("deptSerivceImpl")

@Scope("prototype")

public class DeptSerivceImpl implements DeptService {

public DeptSerivceImpl(){}

public void delete() {

try {

Threadsleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

eprintStackTrace();

}

Systemoutprintln("删除部门");

}

public void save() {

try {

Threadsleep(500);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

eprintStackTrace();

}

Systemoutprintln("保存部门");

}

}

这个是切面测试类:

package aopannotationaspect;

import orgaspectjlangProceedingJoinPoint;

import orgaspectjlangannotationAround;

import orgaspectjlangannotationAspect;

import orgaspectjlangannotationBefore;

import orgaspectjlangannotationPointcut;

import orgspringframeworkstereotypeComponent;

import orgspringframeworkutilStopWatch;

@Aspect

@Component("timeHander")

public class TimeHander {

@Pointcut("bean (Service)")

public void myPointCut(){};

@Before("maPointCut()")

public void myBefore(){

Systemoutprintln("-----执行前置处理-------");

}

@Around("myPointCut()")

public Object handerTime(ProceedingJoinPoint pjp){

try {

// 开始计时

StopWatch watch=new StopWatch(pjpgetTarget()getClass()getName());

watchstart(pjpgetSignature()getName());

Object obj=pjpproceed();

// 停止计时

watchstop();

Systemoutprintln(watchprettyPrint());

return obj;

} catch (Throwable e) {

// TODO Auto-generated catch block

eprintStackTrace();

return null;

}//执行目标

}

}

title: Spring之AOP二

date: 2017-03-25 02:42:16

tags:

execution

日常使用最多的标识符,使用execution标识符的Pointcut表达式格式:

within

指定类型,类型下所有方法。可以使用 和 扩展,like: within(tkzhanghspring)

this和target

Spring中使用this和target实际作用类似

args

指定参数类型,指定参数数量

与execution标识符不同,args标识符会在运行期间动态检查参数类型

@within

指定类型,类型下的所有方法,要求类型标记了指定注解,like:

@target

指定标记了给定注解类型的目标对象的所有方法

@args

指定参数类型,要求参数参数类型标记了指定注解

@annotation

指定标记了指定注解的方法,@Transctional的实现方式

所有@AspectJ形式声明的这些Pointcut表达式最终都会转化成Pointcut的具体实现。

AspectJExpressionPointcut如同他的名字面向AspectJ的pointcut实现,整个继承体系:

使用@Aspect注解标记的类中,具体的Advice形式由具体的Advice注解标示。

注解的方法中需要访问上下文信息最主要的方式:将方法的第一个参数声明为JoinPoint类型

以事务为例,事务管理也是使用AOP,具体是@annotation形式的Pointcut声明(这样我就不用声明Advice了)

当在aFun内调用bFun时事务没有开启,也就是AOP没有生效,原因:

我们期望虚线的调用方式,实际上调用时红色的路线,添加在代理对象上的AOP逻辑在嵌套调用时根本没有机会触发。在事务处理时尤其要注意避免这样的嵌套调用问题。

解决:

不管是那种方式都要注入相关Bean,具体那种更优雅由你来决定了。

在初始化容器的最后,会创建业务bean。创建bean的流程与BeanPostProcessor的创建流程一样( Spring注解--AOP原理(三):BeanPostProcessor创建与注册 )。只是由于在此之前BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)已经注入到容器中,于是在创建业务bean的时候,就可以利用该后置处理器的postProcessAfterInitialization方法中的wrapIfNecessary方法来创建代理对象,进而可以对业务对象进行拦截。请参考 Spring注解--AOP原理(二):AnnotationAwareAspectJAutoProxyCreator

如果业务bean有代理对象,则返回代理对象;否则返回业务bean本身。

最后进入 DefaultAopProxyFactory 类,创建代理对象

最后将代理bean注入到容器中。

以上就是关于spring配置aop的方式有哪些全部的内容,包括:spring配置aop的方式有哪些、如何在sping3.1 MVC中应用aspect注解之AOP、Spring 配置AOP切面注解报错,求教大虾等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9873495.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-02
下一篇 2023-05-02

发表评论

登录后才能评论

评论列表(0条)

保存