1.什么是动态代理?
动态代理是设计模式当中代理模式的一种。
2.什么是代理模式?
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。
3.代理模式有什么好处? 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
4.代理模式一般涉及到的角色有:
抽象角色:声明真实对象和代理对象的共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象。
代理角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象,同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:定义了代理对象所代表的目标对象,代理角色所代表的真实对象,是我们最终要引用的对象,定义了代理对象所代表的目标对象。
1.JDK动态代理
a.真实处理类:(这个一般是一批需要相同处理的类)
//业务处理内容 public class LoginService implements DoService{ /**数据处理*/ DataBaseInterface dao = new DataBaseInterfaceMySqlImp(); /**系统服务*/ SystemSerivce systemService = new SystemSerivce(); public Map<String, Object> doService(HttpServletRequest request, HttpServletResponse response) { @SuppressWarnings("unchecked") Map<String, Object> reqMap = (Map<String, Object>)request.getAttribute("REQMAP"); //获取入参 String loginid = String.valueOf(reqMap.get("LOGINID")); String passwd = String.valueOf(reqMap.get("PASSWORD")); // 获取用户信息 String sql = "SELECT USERSID,PASSWORD,USERNAME FROM users WHERE LOGINID = '" + loginid + "'"; @SuppressWarnings("unchecked") Map<String, Object> rtnMap = ((List<Map<String, Object>>)dao.doSql(sql)).get(0); passwd = SystemUtil.md5Password(passwd, Integer.parseInt(String.valueOf(rtnMap.get("USERSID")))); if(!rtnMap.get("PASSWORD").equals(passwd)) { throw new RuntimeException("密码错误"); } systemService.sessionUser(request, loginid, (String)rtnMap.get("USERNAME")); // 添加session return null; } }
b.抽象处理类为接口:
//一批业务类抽象出接口 public interface DoService { public Map<String, Object> doService(HttpServletRequest request, HttpServletResponse response); }
c.创建代理类
public class ActionToServiceAop implements InvocationHandler{ private Object target; ActionToServiceAop() { super(); } public ActionToServiceAop(Object target) { super(); this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 动态处理:前置处理request HttpServletRequest request = (HttpServletRequest) args[0]; Map<String, Object> reqMap = HttpParameterUtil.getRequstParameters(request); request.setAttribute("REQMAP", reqMap); return method.invoke(target, args); } /** * 获取目标对象的代理对象 * @return 代理对象 */ public Object getProxy() { return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this); } }
c1.说明 代理类实现InvocationHandler接口 invoke为主要处理方法
d.使用
public class LoginAction extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private static DoService rsService; static { // 声明service,向上转型为接口类型 DoService doService = new LoginService(); // 声明代理类型,注入service对象 InvocationHandler invocationHandler = new ActionToServiceAop(doService); // 使用代理类,创建出service对象 rsService = (DoService)Proxy.newProxyInstance(doService.getClass().getClassLoader(), doService.getClass().getInterfaces(), invocationHandler); } @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ // 正常业务调用 rsService.doService(request, response); request.getRequestDispatcher("/WEB-INF/jsps/system/index.jsp").forward(request, response); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ this.doGet(request, response); } }
f.工具类
// 使用:DoService rsService = (DoService)ProxyUtil.getObjectAop(LoginService.class, ActionToServiceAop.class); ; /** * 获取代理类 * @param serviceClass * @param AopClass * @return */ public static Object getObjectAop(Class<?> serviceClass, Class<?> AopClass){ try { Object doService = Class.forName(serviceClass.getName()).newInstance(); InvocationHandler invocationHandler = (InvocationHandler) Class.forName(AopClass.getName()) .getConstructor(Object.class).newInstance(doService); return (DoService)Proxy.newProxyInstance(doService.getClass().getClassLoader(), doService.getClass().getInterfaces(), invocationHandler); } catch (Exception e) { e.printStackTrace(); } return null; }
d.注解进行抽离
/** * 切面变成注解,用以声明使用的代理类 * @author XuZhuohao * @time 2018年2月13日09:57:33 * @version 1.0 */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface AspectOriented { String value(); } /** * 注解aop * @param serviceClass * @return */ public static Object getObjectAop(Class<?> serviceClass){ try { Class<?> doService = Class.forName(serviceClass.getName()); boolean isExists = doService.isAnnotationPresent(AspectOriented.class); // 判断是否存在注解Description if(!isExists){ return null; } // 获取注解对象 AspectOriented aop = doService.getAnnotation(AspectOriented.class); Class<?> AopClass = Class.forName(aop.value()); return getObjectAop(serviceClass, AopClass); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; }
2.cglib动态代理
a.业务类 --真是业务类 b.创建代理类(实现MethodInterceptor接口的类)
public class TestMethodInterceptor implements MethodInterceptor { public Object intercept(Object o, Method method, Object[] objcets, MethodProxy methodProxy) throws Throwable { System.out.println("sayBefore:" + objcets); methodProxy.invokeSuper(o, objcets); System.out.println("sayAfter:" + objcets); return null; } }
c.利用代理创建业务类
Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Service.class); enhancer.setCallback(new TestMethodInterceptor()); Service service = (Service)enhancer.create();
d.即可。。。
本文作者:Yui_HTT
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!