本文参考自:https://www.cnblogs.com/fingerboy/p/5335328.html
在学习Spring框架的时候,由一个重要的思想 就是AOP,面向切面遍程,利用AOP的思想结合Spring的一些API可以实现核心业务和辅助业务的分离,也就是在执行核心业务的时候,将辅助业务加进来。而辅助业务利用日志控制权限一般是一些公共业务,这样就实现了两者的分离。这么做的好处,可以是核心业务更加纯粹,辅助业务也能得到更好的复用。
为什么要代理。
打一个比方,假如我想学习,那么我学习之前必须把书包拿过来,把书包打开,准备好纸笔,开始学习,学习完之后把书放进去,整理书包。明显学习是我的纯粹业务,其他术语公共业务。我们将拿书包,取书,整理书包的事情交给妈妈做,这里的妈妈就是代理。
联想一下,在刚开始接程数据库的时候,我们需要打开连接,执行操作,关闭连接。这么做让我们的业务代码遍得不纯粹。这就是传统开发中存在的问题。
package com.wang.proxy; /** * 简单业务层接口,只有一个save方法 */ interface UserService{ public void saveUser(); } /** * 代理类 */ class UserServiceProxy implements UserService{ private UserService userService; public UserServiceProxy(UserService userService) { super(); this.userService = userService; } public void open(){ System.out.println("1:打开数据库连接"); } public void close(){ System.out.println("3:关闭数据库连接"); } @Override public void saveUser() { this.open(); userService.saveUser(); this.close(); } } /** * 业务层实现类,实现save方法 */ class UserServiceImpl implements UserService{ @Override public void saveUser() { System.out.println("2:保存用户信息"); } } /** * 测试类 */ public class TestProxy { public static void main(String[] args) { UserService userService =new UserServiceProxy(new UserServiceImpl()); userService.saveUser(); } }
上边的例子就是静态代理,静态代理我们必须为所有的代理,单独协议个代理类,于是就有了更加抽象的动态代理,动态代理是利用反射来实现的
如果要使用动态代理,必须要实现InvocationHandler接口, 有如下方法
Object invoke(Object proxy, Method method, Object[] args) :在代理实例上处理方法调
proxy ,表示需要代理的对象
method 表示要操作的方法。
args method 方法要传入的参数
如果想要让代理设计真正可用,我们还必须要由一个代理类对象产生,代理类创建的过程如下:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
该方法返回一个指定的代理实例。
loader:dinginess代理的类加载器
interface ,代理类要实现的接口列表
h 指派方法调用的处理程序
动态代理的代码如下
class ServiceProxy implements InvocationHandler { private Object target=null;//保存真实业务对象 /** * 返回动态代理类的对象,这样用户才可以利用代理类对象去操作真实对象 * @param obj 包含有真实业务实现的对象 * @return 返回代理对象 */ public Object getProxy(Object obj) { this.target=obj;//保存真实业务对象 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj .getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=method.invoke(target, args);//通过反射调用真实业务对象的业务方法,并且返回 return result; } }
public class TestProxy { public static void main(String[] args) { UserService service=(UserService) new ServiceProxy().getProxy(new UserServiceImpl()); service.saveUser(); } }