注意:本文所有的class使用的static修饰主要是为了能在一个类里面测试。实际项目中不应该这样做的,应该分包分class。
文字描述不是很多,还是看代码比较好理解吧...
代理模式
是一种 设计模式
,简单说即是在不改变源码的情况下,实现对目标对象的功能扩展。
使用场景:如在方法执行前后计算执行时间,记录日志等。在不改变原码的条件下实现这些功能的扩展。
public class StaticProxyByExtendTest { //目标对象 public static class UserServiceImpl { public void login(String username, String pwd) { System.out.println("Welcome " + username); } } //代理对象 public static class UserServiceImplProxy extends UserServiceImpl{ public void login(String username, String pwd) { System.out.println("before.... ");//代理额外逻辑 super.login(username, pwd);//调用原实现方法 System.out.println("after.... ");//代理额外逻辑 } } //测试 public static void main(String[] args) { UserServiceImpl ee = new UserServiceImplProxy(); ee.login("Stephen", "123"); } }
public class StaticProxyByGroupTest { public interface UserService { public void login(String username, String pwd); } //目标对象 public static class UserServiceImpl implements UserService { @Override public void login(String username, String pwd) { System.out.println("Welcome " + username); } } //代理对象 public static class UserServiceImplProxy implements UserService { private UserService userService; public UserServiceImplProxy(UserService userService) { this.userService = userService; } @Override public void login(String username, String pwd) { System.out.println("before.... ");//代理额外逻辑 userService.login(username, pwd);//调用原实现方法 System.out.println("after.... ");//代理额外逻辑 } } public static void main(String[] args) { UserService target = new UserServiceImpl(); UserService tt = new UserServiceImplProxy(target); tt.login("Stephen", "123"); } }
使用聚合方式我们还可以添加其他的代理对象来对已经代理的对象继续做增强代理。
主要实现是使用JDK自带的Proxy类来实现
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler.
动态代理不需要对方法逐一实现代理,通过反射循环所有的接口方法,统一动态的加上代理逻辑。我们也可以通过执行方法的名字来过滤当前方法是否需要代理。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyByJDKTest { public interface UserService { public void login(String username, String pwd); } //目标对象 public static class UserServiceImpl implements UserService { @Override public void login(String username, String pwd) { System.out.println("Welcome " + username); } } //代理对象1 public static class UserServiceImplProxy { private UserService userServiceProxy; public UserServiceImplProxy(UserService userService) { UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before.... ");//代理额外逻辑 Object returnValue = method.invoke(userService, args); System.out.println("after.... ");//代理额外逻辑 return returnValue; } }); this.userServiceProxy = proxy; } public UserService getProxy() { return this.userServiceProxy; } } //获取动态代理对象的公共方法 @SuppressWarnings("unchecked") public static <T> T getJDKProxy(T t) { T proxy = (T) Proxy.newProxyInstance( t.getClass().getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before.... ");//代理额外逻辑 Object returnValue = method.invoke(t, args); System.out.println("after.... ");//代理额外逻辑 return returnValue; } }); return proxy; } public static void main(String[] args) { UserService target = new UserServiceImpl(); //代理对象1 UserServiceImplProxy proxy = new UserServiceImplProxy(target); proxy.getProxy().login("Stephen", "123"); //代理对象 UserService jdkProxy = getJDKProxy(target); jdkProxy.login("JDK Stephen", "123"); } }
JDK Proxy动态代理进一步优化:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynamicProxyByJDKTest2 { //目标接口 public interface UserService { public void login(String username, String pwd); } //目标对象 public static class UserServiceImpl implements UserService { @Override public void login(String username, String pwd) { System.out.println("Welcome " + username); } } //代理对象 public static class UserServiceImplProxy extends JDKProxy { public UserService userServiceProxy; public UserServiceImplProxy(UserService userService) { this.userServiceProxy = getJDKProxy(userService); } @Override protected void before(Method method) { System.out.println("before.... ");//代理额外逻辑 } @Override protected void after(Method method) { System.out.println("after.... ");//代理额外逻辑 } } //Common proxy object class public static abstract class JDKProxy { protected abstract void before(Method method); protected abstract void after(Method method); @SuppressWarnings("unchecked") protected <T> T getJDKProxy(T t) { T proxy = (T) Proxy.newProxyInstance( t.getClass().getClassLoader(), t.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(method);//代理额外逻辑 Object returnValue = method.invoke(t, args); after(method);//代理额外逻辑 return returnValue; } }); return proxy; } } public static void main(String[] args) { UserService target = new UserServiceImpl(); //代理对象 UserServiceImplProxy proxy = new UserServiceImplProxy(target); proxy.userServiceProxy.login("Stephen", "123"); } }
在Spring的AOP编程中:
需要引用spring-core.jar Spring Core » 5.1.8.RELEASE
import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class DynamicProxyBySpringCglibTest { //目标接口 public interface UserService { public void login(String username, String pwd); } //目标对象 public static class UserServiceImpl implements UserService { @Override public void login(String username, String pwd) { System.out.println("Welcome " + username); } } //代理对象 public static class ProxyFactory implements MethodInterceptor { private Object target; public ProxyFactory(Object target) { this.target = target; } public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before.... ");//代理额外逻辑 Object returnValue = method.invoke(target, args); System.out.println("after.... ");//代理额外逻辑 return returnValue; } } public static void main(String[] args) throws Exception { UserService target = new UserServiceImpl(); UserService proxy = (UserService) new ProxyFactory(target).getProxyInstance(); proxy.login("Stephen", "123"); } }
主要优化点:
import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class DynamicProxyBySpringCglibTest1 { //目标接口 public interface UserService { public void login(String username, String pwd); } //目标对象 public static class UserServiceImpl implements UserService { @Override public void login(String username, String pwd) { System.out.println("Welcome " + username); } } //Common代理对象 public static abstract class ProxyFactory implements MethodInterceptor { private Object target; public ProxyFactory(Object target) { this.target = target; } public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } protected abstract void before(Method method); protected abstract void after(Method method); @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { before(method); Object returnValue = method.invoke(target, args); after(method); return returnValue; } } //具体代理对象 public static class UserServiceProxy extends ProxyFactory { public UserServiceProxy(Object target) { super(target); } @Override protected void before(Method method) { System.out.println("before.... " + method.getName());//代理额外逻辑 } @Override protected void after(Method method) { System.out.println("after.... " + method.getName());//代理额外逻辑 } } public static void main(String[] args) throws Exception { UserService target = new UserServiceImpl(); UserService proxy = (UserService) new UserServiceProxy(target).getProxyInstance(); proxy.login("Stephen", "123"); } }