spring4--动态代理

 

JDK demo

过程

1.创建目标接口和目标实现类

2.定义实现 InvocationHandler 的类(调用处理器),实现功能增强的控制访问功能。截取对目标方法的调用。

3.定义测试类。用Proxy动态创建代理类,调用代理类的方法。

 

package com.cn.service;

public interface TargetInter {

    public String doSomething(String str);
}



package com.cn.service;

public class TargetInterImpl implements TargetInter {

    @Override
    public String doSomething(String str) {
        System.out.println("do something:"+str);
        return str;
    }

}




package com.cn.service;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

    private Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    /**
     * Object proxy : JVM生成的代理对象
     * Method method : 业务方法(目标方法)
     * Object[] args :   业务方法的参数列表
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("into invoke method");
        System.out.println(proxy.getClass().getName());
        Object result = method.invoke(target, args);
        
        if(result !=null) {
            String str = (String) result;
            result = str.toUpperCase();
            System.out.println("目标方法实现业务的增强");
        }
        return result;
    }

}




package com.cn.service;

import java.lang.reflect.Proxy;

public class MyTest {

    public static void main(String[] args) {
        //1.创建目标对象,但是不能直接访问目标对象
        TargetInter target = new TargetInterImpl();
        //2.创建 调用处理器对象,传入目标对象,代理对它的访问。(代理对象是,任意一个实例化了的类)
        MyInvocationHandler handler = new MyInvocationHandler(target);
        //3.使用proxy创建代理对象
        TargetInter service = (TargetInter)Proxy.newProxyInstance(
                target.getClass().getClassLoader(), 
                target.getClass().getInterfaces(),
                handler);
        //4.执行代理对象进行业务方法的执行,活的增强的功能。
        System.out.println(service.doSomething("ceshi"));
    }

}



into invoke method
com.sun.proxy.$Proxy0
do something:ceshi
目标方法实现业务的增强
CESHI

 

cglib demo

cglib能够动态生成字节码文件。通过继承关系生成。代理类是目标类的子类。在子类完成功能的增强。

一个要求:目标类不能是final的,目标方法不是 final的

步骤:

1.定义目标类

2.定义方法拦截器对象,实现MethodInterceptor。实现访问控制和功能增强。

3.创建代理工厂

4.创建测试类,生产代理对象,调用代理对象的业务方法。

 

package com.cn.service;

public class TargetInterImpl  {

    public String doSomething(String str) {
        System.out.println("do something:"+str);
        return str;
    }

}



package com.cn.service;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class MyInvocationHandler implements MethodInterceptor {

    private Object target;
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    /**
     * 访问控制 和 功能增强
     * Object arg0:  代理对象
     * Method arg1 : 目标方法
     * Object[] arg2: 目标方法的参数列表
     * MethodProxy arg3 : 目标方法的代理对象
     */
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("into  intercept");
        //目标方法的调用
        Object result = method.invoke(target, args);
        System.out.println("增强的功能:日志操作");
        return result;
    }


}



package com.cn.service;

import org.springframework.cglib.proxy.Enhancer;

//工厂模式,工厂方法创建代理对象
public class FactorProxy {

    public Object creatProxy(Object target) {
        //使用cglib生成代理对象
        
        //定义 Enhancer 对象
        Enhancer en = new Enhancer();
        //指定目标类。
        en.setSuperclass(TargetInterImpl.class);
        //指定方法拦截器对象,完成功能的增强
        en.setCallback(new MyInvocationHandler(target));
        //创建代理对象
        return en.create();
    }
}



package com.cn.service;

public class MyTest {

    public static void main(String[] args) {
        //创建目标对象
        TargetInterImpl target = new TargetInterImpl();
        //使用工厂创建代理
        TargetInterImpl proxy = (TargetInterImpl)new FactorProxy().creatProxy(target);
        System.out.println(proxy.getClass().getName());
        //调用代理类的业务方法
        System.out.println(proxy.doSomething("ceshi"));
    }

}




com.cn.service.TargetInterImpl$$EnhancerByCGLIB$$c7a6ba07
into  intercept
do something:ceshi
增强的功能:日志操作
ceshi

 

posted @ 2019-07-28 13:59  walkerluo  阅读(244)  评论(0编辑  收藏  举报