java动态代理 和cglib

理解:动态代理主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法

  代理对象与被代理对象继承相同的接口,他们并没有继承关系

模拟javaEE的service层

1、定义接口

UserService.java

public interface UserService {
    public void save();
    public void delete();
    public void update();
    public void find();
}

2、定义实现类

UserServiceImpl.java

public class UserServiceImpl implements UserService {

    public void save() {
        System.out.println("保存");
    }

    public void delete() {
        System.out.println("删除");
    }

    public void update() {
        System.out.println("更新");
    }

    public void find() {
        System.out.println("查找");
    }
}

3、增强类(动态代理)

UserServiceProxyFactory.java

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

public class UserServiceProxyFactory implements InvocationHandler {

    //要增强的对象
    private UserService us;
    
    public UserServiceProxyFactory(UserService us){
        this.us = us;
    }
    
    public UserService getUserServiceProxy(){
        //生成动态代理
        //动态代理参数一:一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
        //参数二:被代理对象的接口,(一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了)
        //参数三:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上(因为继承了InvocationHandler所以参数三可以传this)
        UserService usProxy = (UserService) Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),
                UserServiceImpl.class.getInterfaces(),
                this);
        return usProxy;
    }

    
    //增强方法
    //proxy:指代我们所代理的那个真实对象
    //method:指代的是我们所要调用真实对象的某个方法的Method对象
    //args:指代的是调用真实对象某个方法时接受的参数
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //调用该方法内容前增强
        System.out.println("打开事务");
        Object invoke = method.invoke(us, args);
        //调用该方法后增强
        System.out.println("关闭事物");
        return invoke;
    }
    
}

4、测试类

Demo.java

public class Demo {

    @Test
    public void testProxy(){
        UserService us = new UserServiceImpl();
        UserServiceProxyFactory factory = new UserServiceProxyFactory(us);
        UserService usProxy = factory.getUserServiceProxy();
    //代理对象与被代理对象实现了相同的接口
    //代理对象 与 被代理对象没有继承关系
        usProxy.save();
    }
    
}

5、增强类(cglib代理)

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

import cn.itcast.service.UserService;
import cn.itcast.service.UserServiceImpl;

//cglib代理
public class UserServiceProxyFactory2 implements MethodInterceptor {
    

    public UserService getUserServiceProxy(){
        
        Enhancer en = new Enhancer();//帮我们生成代理对象
        
        en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
        
        en.setCallback(this);//代理要做什么
        
        UserService us = (UserService) en.create();//创建代理对象
        
        return us;
    }

    @Override
    public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
        //打开事务
        System.out.println("打开事务!");
        //调用原有方法
        Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
        //提交事务
        System.out.println("提交事务!");
        
        return returnValue;
    }


}

6、测试类

public class Demo {
    
    @Test
    public void fun2(){
        
        UserServiceProxyFactory2 factory = new UserServiceProxyFactory2();
        
        UserService usProxy = factory.getUserServiceProxy();
        
        usProxy.save();
        
        //判断代理对象是否属于被代理对象类型
        //代理对象继承了被代理对象=>true
        System.out.println(usProxy instanceof UserServiceImpl );//true
    }
}

总结:java动态代理:所代理对象与被代理对象继承相同的接口,他们并没有继承关系,cglib代理:代理对象继承了被代理对象(如果目标对象被final修饰,那么该类无法使用cglib代理)

   java动态代理:需要被代理的类有实现某个接口,cglib代理:可以代理一般类,不需要被代理类实现任何接口

posted @ 2017-08-24 15:41  发福大叔  阅读(298)  评论(0编辑  收藏  举报