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代理:可以代理一般类,不需要被代理类实现任何接口