spring aop 動態代理 兩種方式實現動態代理

1)jdk Proxy.newInstance(ClassLoader loader,Interface[] interfaces,Class clazz);

這種方法主要是代理接口,不能代理類。

第一步實現invocationHandler接口

public class Proxy implements InvocationHandler{

    private TestInterface object;

    public Proxy(TestInterface testItf){
        this.object = testItf;
    }

    public PersonAction getInstace(){
        return (TestInterface) Proxy.newProxyInstance(this.getClass().getClassLoader(),new Class[]{TestInterface.class},this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("args are "+method.getName());
        // 在調用實際方法之前可以做很多前置操作
        return method.invoke(pa,args);
    }
}

然後就是寫一個TestInterface的接口和兩個實現了該接口的實現類,

public interface TestInterface {
    void bigAct();
}

public class Programmer implements TestInterface {
    public void bigAct(){
        println("i do program every day.i can be a great programmer.");
    }
}

public class Dancer implements TestInterface {
    public void bigAct(){
        println("i dance every day.i can be a great dancer.");
    }
}

測試代理類

public class ActionMain {

        public static void main(String[] args) {
            Programmer p2 = new Programmer();

            TestInterface p = new Proxy(p2).getInstace();
            p.bigAct();
            //這裏看到p2注入到Proxy中,並返回了一個Instance對象,然後再執行p的bigAct方法。
            //具體Proxy.newInstance()實現是通過        
            //class.getConstructor().newInstance(Invocationhandler);
            //即 ConstructorAccessor.newInstance(Object[] var1);
            //我們可以在調用具體的方法前,做很多前置或者是後置操作,這也是aop的思想。
        }
}


public interface ConstructorAccessor {
    Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException;
}

 

2)CGLib動態代理

第一步實現代理類

public class ProxyCglib implements MethodInteceptor{

    Object obj;

    public Object newInstance(Object object){
        this.obj = object;
        Enhancer enhancer = new Enhancer();
        enhancer.setCallback(this);
        enhancer.setSuperClass(object.getClass());
        return enhancer.create();
    }

    @Override
    public void intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)throws Throwable {
        return method.invoke(obj,args);//兩種方式都是通過反射來實現方法的調用。
    }
}

和jdk動態代理的區別就是cglib可以代理類,而jdk只能代理接口,如果沒有實現接口,就代理不了,springboot動態代理自動在兩者之間切換,如果類實現了接口就用cglib如果沒有就用cglib。當然cglib動態代理還要引入asm的jar包。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章