欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

【Spring-AOP】Spring提供的AOP开发方式和底层AOP开发方式

时间:2023-08-05
Spring提供的AOP方式

@Component@Aspectpublic class AopAspect {@Pointcut(value = "execution(* com.ztryou.service.PersonServiceImpl.*(..))")public void pointcut() {}@Before("pointcut()")public void beforeAdvice(JoinPoint point) throws Exception {System.out.println("befor");}@Around(value = "pointcut()")public Object aroundAdvice(ProceedingJoinPoint pjp) {Object obj = null;try {System.out.println("around before");MethodSignature ms = (MethodSignature) pjp.getSignature();Object target = pjp.getTarget();Method method = ms.getMethod();method.invoke(target, 1);obj = pjp.proceed();System.out.println("around after");} catch (Throwable e) {e.printStackTrace();}return obj;}@AfterReturning(value = "pointcut()", returning = "ret")public void afterReturningAdvice(Object ret) {System.out.println("after return");}@AfterThrowing(value = "pointcut()", throwing = "ex")public void afterThrowingAdvice(Exception ex) {System.out.println("after Throw");}@After("pointcut()")public void afterFinallyAdvice() {System.out.println("after");}}

SpringAOP的底层实现

主要设计三个方面:

advisor:切面,切面则包含下面的切点和拦截器

public interface Advisor {Advice getAdvice();。。。。。}public interface PointcutAdvisor extends Advisor {Pointcut getPointcut();}

pointcut: 切点

public interface Pointcut {// 用来匹配类ClassFilter getClassFilter();// 更细粒度的匹配,匹配方法MethodMatcher getMethodMatcher();}

advice:增强(拦截器,用于执行自己的逻辑)

public interface Advice {}

这里注意,增强只是一个标识接口,用来表示这是一个增强类。我们要增强的逻辑是要实现MethodInterceptor接口,在invoke方法中写的。

public interface MethodInterceptor extends Interceptor {Object invoke(MethodInvocation invocation) throws Throwable;}

每个都有自己的接口,只需要自己实现子类。

Spring提供的现成的类

RegexpMethodPointcutAdvisor类:通过解析正则表达式匹配目标方法。当然它的内部是使用的正则表达式的节点类:JdkRegexpMethodPointcut,开发这直接编写自己的拦截器就好。

使用:

// 这里要设置你想拦截的方法的表达式。 // 这个表达式会复制给切点类JdkRegexpMethodPointcut .*set.* .*absquatulate

DefaultPointcutAdvisor这个类只是一个切面类,需要自己定义切点和增强。默认的切点是匹配所有的类,如果这样符合预期,那么只需要定义增强类。

增强的拦截

增强的逻辑是放在拦截器中执行的:

public class DebugInterceptor implements MethodInterceptor {// MethodInvocation 是一个拦截器执行链,调用proceed()会执行下一个拦截器。// 所以可以在proceed()前后执行自己的逻辑。 public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Before: invocation=[" + invocation + "]"); Object rval = invocation.proceed(); System.out.println("Invocation returned"); return rval; }}

使用ProxyFactoryBean创建代理

一般创建代码的时候,spring通过bean的postBeanProcessor处理器,对bean进行拦截,创建代理。还有一种方法就是通过ProxyFactoryBean创建代理,但是这种方式只能对一个bean进行代理。例子可以看:TransactionProxyFactoryBean

使用spring aop自己创建代理

ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);factory.addAdvice(myMethodInterceptor);factory.addAdvisor(myAdvisor);MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();

自动代理

之前介绍的都是代理一个指定类。那么spring是如何代理容器的类呢?使用的是beanPostProcessor处理器。在初始化后方法中,找到所有切面类,对该bean进行匹配。如果符合,就代理。

包装代理对象

org.springframework.aop.framework.Advised接口实现了可以对代理对象的所有操作。

Advisor[] getAdvisors();void addAdvice(Advice advice) throws AopConfigException;void addAdvice(int pos, Advice advice) throws AopConfigException;void addAdvisor(Advisor advisor) throws AopConfigException;void addAdvisor(int pos, Advisor advisor) throws AopConfigException;int indexOf(Advisor advisor);boolean removeAdvisor(Advisor advisor) throws AopConfigException;void removeAdvisor(int index) throws AopConfigException;boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;boolean isFrozen();

封装之后可以进行调节:

Advised advised = (Advised) myObject;Advisor[] advisors = advised.getAdvisors();int oldAdvisorCount = advisors.length;System.out.println(oldAdvisorCount + " advisors");// Add an advice like an interceptor without a pointcut// Will match all proxied methods// Can use for interceptors, before, after returning or throws adviceadvised.addAdvice(new DebugInterceptor());// Add selective advice using a pointcutadvised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。