需要的架包:在spring中提供对CGLIB的支持
一、JDK的动态代理
1.接口IUserDao
1 package cn.itcast.spring3.jdk.proxy; 2 3 public interface IUserDao { 4 5 public void add(); 6 public void update(); 7 8 }
2.接口的实现类UserDaoImpl.java
1 package cn.itcast.spring3.jdk.proxy; 2 3 public class UserDaoImpl implements IUserDao { 4 5 @Override 6 public void add() { 7 System.out.println("add......"); 8 9 } 10 11 @Override 12 public void update() { 13 System.out.println("update........."); 14 15 } 16 17 }
3.JDKProxy.java
1 package cn.itcast.spring3.jdk.proxy; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 7 /** 8 * jdk动态代理 这个是必须有接口和实现类 9 * 使用动态代理增强指定方法 10 * @author Administrator 11 * 12 */ 13 public class JDKProxy implements InvocationHandler { 14 15 private IUserDao userDao; 16 public JDKProxy(IUserDao userDao) { 17 super(); 18 this.userDao = userDao; 19 } 20 21 22 public IUserDao createProxy(){ 23 IUserDao proxy = (IUserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), 24 userDao.getClass().getInterfaces(), this); 25 return proxy; 26 } 27 28 /** 29 * 所有的方法都要经过这个方法过滤 30 */ 31 @Override 32 public Object invoke(Object proxy, Method method, Object[] args) 33 throws Throwable { 34 if("add".equals(method.getName())){ 35 System.out.println("日志的记录"); 36 Object result = method.invoke(userDao, args); 37 return result; 38 } 39 return method.invoke(userDao, args); 40 } 41 42 }
4.测试类:TestJdkProxy.java
1 package cn.itcast.spring3.jdk.proxy; 2 3 import org.junit.Test; 4 5 public class TestJDKProxy { 6 7 @Test 8 public void jdkProxyText(){ 9 //创建真是对象 10 IUserDao userDao = new UserDaoImpl(); 11 //创建一个代理对象 12 IUserDao proxy = new JDKProxy(userDao).createProxy(); 13 proxy.add(); 14 proxy.update(); 15 } 16 17 }
二、CGLIB的代理
1.UserDao.java
1 package cn.itcast.spring3.cglib.proxy; 2 3 public class UserDao { 4 5 public void add(){ 6 System.out.println("add........"); 7 } 8 9 public void update(){ 10 System.out.println("update"); 11 } 12 13 14 }
2.CGLIBProxy.java
1 package cn.itcast.spring3.cglib.proxy; 2 3 import java.lang.reflect.Method; 4 5 import org.springframework.cglib.proxy.Enhancer; 6 import org.springframework.cglib.proxy.MethodInterceptor; 7 import org.springframework.cglib.proxy.MethodProxy; 8 import org.springframework.util.ReflectionUtils.MethodCallback; 9 10 /** 11 * 通过指定子类来实现代理 12 * 即任何一个类都可以代理 13 * 14 * @author Administrator 15 * 16 */ 17 public class CGLIBProxy implements MethodInterceptor { 18 19 //你要代理的父类 20 private UserDao userDao; 21 22 public CGLIBProxy(UserDao userDao) { 23 super(); 24 this.userDao = userDao; 25 } 26 27 //创建代理 28 public UserDao createProxy(){ 29 /* 30 * 使用CGLIB生成代理 31 */ 32 //1.创建核心类 enhancer:增强 33 Enhancer enhancer = new Enhancer(); 34 //2.为其设置父类 35 enhancer.setSuperclass(userDao.getClass()); 36 //3.设置回调 37 enhancer.setCallback(this); 38 //4.创建代理 39 return (UserDao)enhancer.create(); 40 41 } 42 43 /** 44 * 对add方法进行增强 45 */ 46 @Override 47 public Object intercept(Object proxy, Method method, Object[] args, 48 MethodProxy methodProxy) throws Throwable { 49 if("add".equals(method.getName())){ 50 System.out.println("写入日志"); 51 Object result = methodProxy.invokeSuper(proxy, args); 52 return result; 53 } 54 return methodProxy.invokeSuper(proxy, args); 55 } 56 57 }
3.TestCGLIBProxy.java
1 package cn.itcast.spring3.cglib.proxy; 2 3 import org.junit.Test; 4 5 public class TestCGLIBProxy { 6 7 8 9 @Test 10 public void CGLIBProxyTest(){ 11 UserDao proxy = new CGLIBProxy(new UserDao()).createProxy(); 12 proxy.add(); 13 proxy.update(); 14 } 15 16 }
三、JDK的动态代理必须有接口,而CGLIB的代理,则不需要接口,即任何一个类都可以生成代理