一、cglib代理方式
public class UserService {public void login() {System.out.println("login...");}public void logout() {System.out.println("logout...");}}
使用动态代理(不修改源码前提下)增强上面逻辑
@Testpublic void cglibProxyTest() {UserService target = new UserService();// 通过cglib技术Enhancer enhancer = new Enhancer();enhancer.setSuperclass(UserService.class);// 增加增强逻辑enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {//o:代理对象 methoProxy:代理方法//objects:方法入参@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("login before...");Object result = methodProxy.invoke(target, objects);//Object result = method.invoke(target, objects);System.out.println("login after...");return result;}},new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println("logout before...");Object result = methodProxy.invoke(target, objects);//Object result = method.invoke(target, objects);System.out.println("logout after...");return result;}}});enhancer.setCallbackFilter(new CallbackFilter() {@Overridepublic int accept(Method method) {if (method.getName().equals("login"))return 0;return 1;//数字对应new Callback[]数组索引}});// 生成UserService代理对象UserService userService = (UserService) enhancer.create();// 使用代理对象执行原有逻辑,就会执行增强逻辑userService.login();userService.loginout();}login before...login...login after...logout before...logout...logout after...
cglib是基于父子类机制,不依赖接口。被代理类时父类,新生成的代理类时子类。使用代理类生成代理对象。
二、JDK代理方式
此种代理方式,只能代理接口,利用接口产生jdk代理对象。
public interface ServiceInterface {void login();void logout();}
@Testpublic void jdkProxyTest(){UserService target = new UserService();ServiceInterface serviceInterface = (ServiceInterface)Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{ServiceInterface.class}, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before");return method.invoke(target,args);}});serviceInterface.login();}
三、Spring动态代理
Spring中对上面两种代理,进行了封装,封装出来的类叫做ProxyFactory(创建代理对象的一个工厂)
@Testpublic void springProxyTest(){UserService target = new UserService();ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.setTarget(target);proxyFactory.addAdvice(new org.aopalliance.intercept.MethodInterceptor() {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("before");Object proceed = invocation.proceed();System.out.println("after");return proceed;}});UserService userService = (UserService) proxyFactory.getProxy();userService.login();}
ProxyFactory底层会进行判断,如果UserService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术。
