一、cglib代理方式

  1. public class UserService {
  2. public void login() {
  3. System.out.println("login...");
  4. }
  5. public void logout() {
  6. System.out.println("logout...");
  7. }
  8. }

使用动态代理(不修改源码前提下)增强上面逻辑

  1. @Test
  2. public void cglibProxyTest() {
  3. UserService target = new UserService();
  4. // 通过cglib技术
  5. Enhancer enhancer = new Enhancer();
  6. enhancer.setSuperclass(UserService.class);
  7. // 增加增强逻辑
  8. enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
  9. //o:代理对象 methoProxy:代理方法
  10. //objects:方法入参
  11. @Override
  12. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  13. System.out.println("login before...");
  14. Object result = methodProxy.invoke(target, objects);
  15. //Object result = method.invoke(target, objects);
  16. System.out.println("login after...");
  17. return result;
  18. }
  19. },new MethodInterceptor() {
  20. @Override
  21. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  22. System.out.println("logout before...");
  23. Object result = methodProxy.invoke(target, objects);
  24. //Object result = method.invoke(target, objects);
  25. System.out.println("logout after...");
  26. return result;
  27. }
  28. }});
  29. enhancer.setCallbackFilter(new CallbackFilter() {
  30. @Override
  31. public int accept(Method method) {
  32. if (method.getName().equals("login"))
  33. return 0;
  34. return 1;//数字对应new Callback[]数组索引
  35. }
  36. });
  37. // 生成UserService代理对象
  38. UserService userService = (UserService) enhancer.create();
  39. // 使用代理对象执行原有逻辑,就会执行增强逻辑
  40. userService.login();
  41. userService.loginout();
  42. }
  43. login before...
  44. login...
  45. login after...
  46. logout before...
  47. logout...
  48. logout after...

cglib是基于父子类机制,不依赖接口。被代理类时父类,新生成的代理类时子类。使用代理类生成代理对象。

二、JDK代理方式

此种代理方式,只能代理接口,利用接口产生jdk代理对象。

  1. public interface ServiceInterface {
  2. void login();
  3. void logout();
  4. }
  1. @Test
  2. public void jdkProxyTest(){
  3. UserService target = new UserService();
  4. ServiceInterface serviceInterface = (ServiceInterface)Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{ServiceInterface.class}, new InvocationHandler() {
  5. @Override
  6. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  7. System.out.println("before");
  8. return method.invoke(target,args);
  9. }
  10. });
  11. serviceInterface.login();
  12. }

三、Spring动态代理

Spring中对上面两种代理,进行了封装,封装出来的类叫做ProxyFactory(创建代理对象的一个工厂)

  1. @Test
  2. public void springProxyTest(){
  3. UserService target = new UserService();
  4. ProxyFactory proxyFactory = new ProxyFactory();
  5. proxyFactory.setTarget(target);
  6. proxyFactory.addAdvice(new org.aopalliance.intercept.MethodInterceptor() {
  7. @Override
  8. public Object invoke(MethodInvocation invocation) throws Throwable {
  9. System.out.println("before");
  10. Object proceed = invocation.proceed();
  11. System.out.println("after");
  12. return proceed;
  13. }
  14. });
  15. UserService userService = (UserService) proxyFactory.getProxy();
  16. userService.login();
  17. }

ProxyFactory底层会进行判断,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术。