@Component @Aspect public 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 advice advised.addAdvice(new DebugInterceptor()); // Add selective advice using a pointcut advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice)); assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)