一、cglib代理方式
public class UserService {
public void login() {
System.out.println("login...");
}
public void logout() {
System.out.println("logout...");
}
}
使用动态代理(不修改源码前提下)增强上面逻辑
@Test
public void cglibProxyTest() {
UserService target = new UserService();
// 通过cglib技术
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
// 增加增强逻辑
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
//o:代理对象 methoProxy:代理方法
//objects:方法入参
@Override
public 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() {
@Override
public 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() {
@Override
public 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();
}
@Test
public void jdkProxyTest(){
UserService target = new UserService();
ServiceInterface serviceInterface = (ServiceInterface)Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{ServiceInterface.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
return method.invoke(target,args);
}
});
serviceInterface.login();
}
三、Spring动态代理
Spring中对上面两种代理,进行了封装,封装出来的类叫做ProxyFactory(创建代理对象的一个工厂)
@Test
public void springProxyTest(){
UserService target = new UserService();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(target);
proxyFactory.addAdvice(new org.aopalliance.intercept.MethodInterceptor() {
@Override
public 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技术。