Spring AOP两种实现机制是什么?

Spring AOP两种实现机制是什么?

Spring
id="iframeu788097_0" src="http://pos.baidu.com/acom?rdid=788097&dc=2&di=u788097&dri=0&dis=0&dai=1&ps=247x1206&dcb=BAIDU_UNION_define&dtm=BAIDU_DUP_SETJSONADSLOT&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1454246761341&ti=Spring%20AOP%E4%B8%A4%E7%A7%8D%E5%AE%9E%E7%8E%B0%E6%9C%BA%E5%88%B6%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F%20%E2%80%94%E2%80%94%20IT%E5%85%AC%E5%8F%B8%E9%9D%A2%E8%AF%95%E6%89%8B%E5%86%8C&ari=1&dbv=2&drs=1&pcs=1920x923&pss=1920x273&cfv=0&cpl=27&chi=1&cce=true&cec=UTF-8&tlm=1396013260&ltu=http%3A%2F%2Fwww.mianwww.com%2Fhtml%2F2012%2F11%2F17084.html&ltr=http%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D0wxuEm5wZzhcCbSYOiv6BGm6WUbQxfrpnuuFR_bSxWbC3v5KHhKSz98oWf73QgVprpqmv4139QuKqR_G7WU3Da%26wd%3D%26eqid%3Df0c37c5c0002a4660000000456ae0b40&ecd=1&psr=1920x1080&par=1920x1040&pis=-1x-1&ccd=24&cja=true&cmi=53&col=zh-CN&cdo=-1&tcn=1454246761&qn=0658fd932312088a&tt=1454246761306.46.170.173" width="336" height="280" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="border-width: 0px; border-style: initial; vertical-align: bottom; margin: 0px;">

SPRING是通过动态代理来实现AOP的,SPRING内部提供了2种实现机制
1.如果是有接口声明的类进行AOP,spring调用的是java.lang.reflection.Proxy类来做处理

org.springframework.aop.framework.JdkDynamicAopProxy

       public Object getProxy(ClassLoader classLoader) {

              if (logger.isDebugEnabled()) {

                     Class targetClass = this.advised.getTargetSource().getTargetClass();

                     logger.debug(“Creating JDK dynamic proxy” +

                                   (targetClass != null ? ” for [" + targetClass.getName() + "]” : “”));

              }

              Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);

              return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

       }

org.springframework.aop.framework.ReflectiveMethodInvocation

public Object proceed() throws Throwable {

              //     We start with an index of -1 and increment early.

              if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() – 1) {

                     return invokeJoinpoint();

              }

              Object interceptorOrInterceptionAdvice =

                  this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

              if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {

                     // Evaluate dynamic method matcher here: static part will already have

                     // been evaluated and found to match.

                     InterceptorAndDynamicMethodMatcher dm =

                         (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;

                     if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {

                            return dm.interceptor.invoke(this);

                     }

                     else {

                            // Dynamic matching failed.

                            // Skip this interceptor and invoke the next in the chain.

                            return proceed();

                     }

              }

              else {

                     // It’s an interceptor, so we just invoke it: The pointcut will have

                     // been evaluated statically before this object was constructed.

                     return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

              }

       }

2.如果是没有接口声明的类呢?SPRING通过CGLIB包和内部类来实现

private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable {

 

private final Object target;

 

public StaticUnadvisedInterceptor(Object target) {

this.target = target;

}

 

public Object intercept(Object proxy, Method method, Object[] args,

MethodProxy methodProxy) throws Throwable {

 

Object retVal = methodProxy.invoke(target, args);

return massageReturnTypeIfNecessary(proxy, target, retVal);

}

}

 

 

/**

* Method interceptor used for static targets with no advice chain, when the

* proxy is to be exposed.

*/

private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

 

private final Object target;

 

public StaticUnadvisedExposedInterceptor(Object target) {

this.target = target;

}

 

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

Object oldProxy = null;

try {

oldProxy = AopContext.setCurrentProxy(proxy);

Object retVal = methodProxy.invoke(target, args);

return massageReturnTypeIfNecessary(proxy, target, retVal);

}

finally {

AopContext.setCurrentProxy(oldProxy);

}

}

}

 

 

/**

* Interceptor used to invoke a dynamic target without creating a method

* invocation or evaluating an advice chain. (We know there was no advice

* for this method.)

*/

private class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable {

 

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

Object target = advised.getTargetSource().getTarget();

try {

Object retVal = methodProxy.invoke(target, args);

return massageReturnTypeIfNecessary(proxy, target, retVal);

}

finally {

advised.getTargetSource().releaseTarget(target);

}

}

}

 

 

/**

* Interceptor for unadvised dynamic targets when the proxy needs exposing.

*/

private class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable {

 

public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

Object oldProxy = null;

Object target = advised.getTargetSource().getTarget();

try {

oldProxy = AopContext.setCurrentProxy(proxy);

Object retVal = methodProxy.invoke(target, args);

return massageReturnTypeIfNecessary(proxy, target, retVal);

}

finally {

AopContext.setCurrentProxy(oldProxy);

advised.getTargetSource().releaseTarget(target);

}

}

}

 

我们自己也可以来试试
1.jdk proxy方式

先来一个接口
IHelloWorld.java

package kris.aop.test;

 

public interface IHelloWorld {

 

public void print(String name);

public void write(String sth);

}

 

再来一个实现

HelloWorld.java

package kris.aop.test;

 

public class HelloWorld implements IHelloWorld {

 

public void print(String name){

System.out.println(“HelloWorld “+name);

}

 

public void write(String sth) {

System.out.println(“write “+sth);

}

 

}

 

代理类

DefaultInvocationHandler.java

package kris.aop.test;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

 

public class DefaultInvocationHandler implements InvocationHandler {

 

/**

* 替换外部class调用的方法

* obj                 外部已经已经包装好InvocationHandler的实例

* method        外部方法

* args              方法参数

*/

public Object invoke(Object obj, Method method, Object[] args)

throws Throwable {

String s1 []={“kris”};

String s2 []={“anyone”};

IHelloWorld ihw=new HelloWorld();

System.out.println(“start!”);

method.invoke(ihw,args);

method.invoke(ihw,s1);

Object o=method.invoke(ihw,s2);

System.out.println(“stop!”);

return o;

}

}

 

测试类
Test.java

package kris.aop.test;

 

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

 

public class Test {

 

public static void main(String args []){

Class clazz = new HelloWorld().getClass();

ClassLoader cl = clazz.getClassLoader();

Class classes [] = clazz.getInterfaces();

InvocationHandler ih=new DefaultInvocationHandler();

//用InvocationHandler给HelloWorld进行AOP包装

IHelloWorld ihw=(IHelloWorld) Proxy.newProxyInstance(cl,classes,ih);

ihw.print(“test”);

ihw.write(“test”);

}

}

 

2.用CGLIB包实现,首先不要忘了引入那个包

package kris.aop.cglib.test;

 

public class HelloWorld {

 

public void print(String name){

System.out.println(“HelloWorld “+name);

}

 

public void write(String sth) {

System.out.println(“write “+sth);

}

public void print(){

System.out.println(“HelloWorld”);

}

}

 

代理类(没用内部类,看起来清楚点)

package kris.aop.cglib.test;

 

import java.lang.reflect.Method;

 

import net.sf.cglib.proxy.MethodInterceptor;

import net.sf.cglib.proxy.MethodProxy;

 

public class MethodInterceptorImpl implements MethodInterceptor {

 

public Object intercept(Object obj, Method method, Object[] args,

MethodProxy proxy) throws Throwable {

 

System.out.println(method);

 

proxy.invokeSuper(obj, args);

 

return null;

}

}

 

测试类

 

package kris.aop.cglib.test;

 

import net.sf.cglib.proxy.Enhancer;

 

public class Test {

 

public static void main(String[] args) {

 

Enhancer enhancer = new Enhancer();

 

enhancer.setSuperclass(HelloWorld.class);

//设置回调方法实现类

enhancer.setCallback(new MethodInterceptorImpl());

//实例化已经添加回调实现的HELLOWORLD实例

HelloWorld my = (HelloWorld) enhancer.create();

 

my.print();

}

 

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值