需求:使用AOP方式打印日志
用户service层,接口与实现类
public interface IUserService { void addUser(String name); }public class UserService implements IUserService{ @Override public void addUser(String name) { System.out.println("将"+name+"添加到数据库"); } }
1.静态代理
静态代理,使用一个代理类,需要实现服务的接口,来代理用户的动作,并添加一些另外的东西
public class StaticProxy implements IUserService{ private IUserService userservice = new UserService(); @Override public void addUser(String name) { userservice.addUser(name); System.out.println("我是日志:添加了"+name); } }
效果如下
image.png
2.动态代理
jdk动态代理
jdk动态代理有个前提,就是被代理的类必须要实现接口
还是上面的两个
public class JDKProxy implements InvocationHandler{ private Object object; public Object createProxyInstance(Object object) { this.object = object; return Proxy.newProxyInstance(object.getClass().getClassLoader() , object.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //执行额外的逻辑 System.out.println("我是日志,前置处理"); //执行原来的逻辑 Object invoke = method.invoke(object,args); return invoke; } }
测试用例
@Test public void testJdkProxy() { IUserService userService = new UserService(); JDKProxy jdkProxy = new JDKProxy(); IUserService createProxyInstance = (IUserService)jdkProxy.createProxyInstance(userService); createProxyInstance.addUser("李四"); }
效果如下
image.png
cglib动态代理
因为jdk代理需要被代理类实现接口,没必要为每个类都实现接口,所以就出现了cglib
public class Admin { public void addAdmin(String name) { System.out.println("添加了"+name); } }
cglib代理类
public class CglibProxy implements MethodInterceptor{ private Enhancer enhancer = new Enhancer(); public Object getProxyInstance(Class clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("我是日志:是前置处理"); //通过代理子类来调用父类的方法 Object invoke = proxy.invokeSuper(object, args); System.out.println(args.toString()); return invoke; } }
测试用例
@Test public void testCglibProxy() { CglibProxy cglibProxy = new CglibProxy(); IUserService proxyInstance = (IUserService)cglibProxy.getProxyInstance(UserService.class); proxyInstance.addUser("王五"); }
效果如下
image.png
代码请到码云下载:https://gitee.com/zhangqiye/java-proxy
作者:z七夜
链接:https://www.jianshu.com/p/db860f0391a9