Spring笔记4-AOP
Posted hh6plus
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring笔记4-AOP相关的知识,希望对你有一定的参考价值。
AOP简介:
面向切面编程
首先介绍动态代理:
动态代理可以在类的所有方法之前增加业务逻辑。jdk中的类想要被动态代理,必须实现接口(假设Target实现了接口ITarget)。使用proxy与实现InvocationHandler接口,来实现动态代理(参视频:动态代理)。PHandler实现InvocationHandler接口,其中含有private的Object(被代理对象target)。在自己的invoke方法(参见反射)中先写入自己的代理前业务逻辑,再通过反射方法调用被代理对象的对应方法(即method.invoke(target,args)),最后加上代理后业务逻辑。如果针对不同的业务逻辑增加不同的业务,可以将method传入PHandler的beforeMethod()方法,进而判断不同的method写入不同的beforeMethod方法内容。
实现动态代理的过程为:先产生一个被代理对象target,产生一个PHandler,将target用setter传给PHandler。然后使用ITarget targetProxy = Proxy.newProxyInstance(),将target与handler传入,传入方法为arg0:target.getClass().getClassLoader(),arg1:target.getClass().getInterfaces(),arg2:PHandler。handler中含有我们想加入的业务逻辑,target为被代理对象,含有原来的业务逻辑。
最后执行targetProxy.业务逻辑(业务参数);执行时先执行handler的begin逻辑,再执行target,最后执行handler的end逻辑。
Spring中的AOP实现,背后使用的是动态代理的实现(对有实现的类),对没有实现接口的类直接更改二进制码。
AOP的实现:
Java中实现AOP,需要在Spring的.xml中增加xmlns=“http://.../aop”,xsi:schemalocation中加schema/aop,schema/aop/spring-aop-2.5.xsd(可以在spring的samples中寻找例程,或者dist/resources寻找aop的.xsd)(在IDE的XML Catalog中增加后一个.xsd可以获得IDE的提示功能)。在.xml正文中增加<aop:aspectj-autoproxy/>,即可使用@AspectJ标签(程序会扫描@AspectJ标签并进行动态代理)。
AspectJ:AspectJ是一个专门用于产生动态代理功能的项目。Spring也使用了AspectJ进行AOP实现。使用AJ时要引入AspectJ的两个.jar包。
AOP的使用:
在类名前添加@Aspect标签(表示此类可以作为切面进行织入),并加入@Component(将此类交给Spring初始化,用于织入工作)。在想要在原逻辑前织入的业务逻辑(如beforeMethod())(其实也有将类,属性织入的,暂不讨论)上方加@Before标签(或任何Advice),即实现了将beforeMethod()织入原对象逻辑。
@Before的语法:
@Before("execution(public 返回值类型 com.company.dao.impl.UserDAOImpl.函数名(com.company.model.函数参数类名)”):将被@Before形容的方法织入到execution形容的函数名执行之前。execution是方法织入的专用关键词。
JoinPoint:
切入点,即在原逻辑中的哪些点需要织入切面逻辑;也即在从前往后的业务逻辑中插入切面时,在原逻辑中被织入的位置。
PointCut:
切入点的集合。
@Pointcut("execution(* com.company.someapp.service.*.*(..))")
public void someMethod(){}
代表在com.company.someapp.service下的任何类的任何方法都是someMethod()的切入点。
someMethod可以是空实现,作为Advice的参数。在此之后可以在任何Advice的参数中写someMethod(),即可在此切入点集合中执行。
Advice:
代表在切面上的建议逻辑。如@Before,@After都是切入点上的建议。
Target:
被代理对象(被织入对象)。
Weave:
织入。
AOP支持的AspectJ语法:
execution(public * *(..)):公开的任何返回值的任何方法
execution(* set*(..)):任何返回值的任何方法名为set打头的方法
execution(* com.comp.service.*.*(..)):任何返回值的service包下的任何类的任何方法
execution(* com.comp.service..*.*(..)):任何返回值的service包下及其子包(无限层)的任何类的任何方法
AOP自成语法:
within(com.comp.service.*):
within(com.comp.service..*):
this(com.comp.service.SomeService):
target(com.comp.service.SomeService):
args(java.io.Serializable):
etc.
Advice类型:
@before("execution()")或者Before(someMethod)[参见上PointCut解释]:
@AfterReturning:于目标方法正常返回后执行。
@AfterThrowing:于目标方法抛出异常后执行。
@After:即finally,不论异常或正常返回均执行。
@Around:环绕。被环绕修饰的方法public Object doBasicProfiling(方法名可换),参数为ProcedingJoinPoint pjp(不可换),throws Throwable。
在此方法中先写before织入逻辑,再写Object retVal = pjp.proceed();,再写after织入逻辑,最后 return retVal;。(可参责任链模式的视频)
Advice的参数可以是execution,也可以是someMethod[参见PointCut解释]
以上是关于Spring笔记4-AOP的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC学习笔记——AbstractController