代理模式中的角色:
Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。
RealSubject:具体主题角色,也叫被委托角色、被代理角色。是业务逻辑的具体执行者。
Proxy:代理主题角色,也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作。(最简单的比如打印日志):
先创建一个被代理对象,该对象必须继承一个接口(否则jdk无法产生动态代理)
接口:
1 package com.bxw.service; 2 3 public interface UserService { 4 public String getName(int id); 5 public Integer getAge(int id); 6 }
被代理的对象:
1 package com.bxw.serviceImpl; 2 3 import com.bxw.service.UserService; 4 5 public class UserServiceImpl implements UserService{ 6 7 @Override 8 public String getName(int id) { 9 System.out.println("---getNmae---"); 10 return "Tom"; 11 } 12 13 @Override 14 public Integer getAge(int id) { 15 System.out.println("---getAge---"); 16 return 17; 17 } 18 19 }
Handler:
1 package com.bxw.invocation; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 6 public class MyInvocationHandler implements InvocationHandler { 7 //动态代理要有一个被代理的对象 8 private Object target; 9 10 MyInvocationHandler() { 11 super(); 12 } 13 14 public MyInvocationHandler(Object target) { 15 super(); 16 this.target = target; 17 } 18 19 @Override 20 public Object invoke(Object o, Method method, Object[] args) throws Throwable { 21 if("getName".equals(method.getName())){ 22 System.out.println("++++++before " + method.getName() + "++++++"); 23 Object result = method.invoke(target, args); 24 System.out.println("++++++after " + method.getName() + "++++++"); 25 return result; 26 }else{ 27 Object result = method.invoke(target, args); 28 return result; 29 } 30 31 } 32 }
Test:
1 package com.bxw.test; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Proxy; 5 6 import com.bxw.invocation.MyInvocationHandler; 7 import com.bxw.service.UserService; 8 import com.bxw.serviceImpl.UserServiceImpl; 9 10 /** 11 * jdk要实现动态代理那么该类必须实现一个接口 12 * @author Admin 13 * 14 */ 15 public class TestDemo { 16 public static void main(String[] args) { 17 UserService userService = new UserServiceImpl(); //被代理对象 18 InvocationHandler invocationHandler = new MyInvocationHandler(userService); 19 //classLoader,interface,产生业务逻辑的Hanfler 20 UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(), 21 userService.getClass().getInterfaces(), invocationHandler);//产生的代理对象 22 System.out.println(userServiceProxy.getName(1)); 23 System.out.println(userServiceProxy.getAge(1)); 24 } 25 }
Proxy.newProxyInstance()这个方法有三个参数.第一个是定义代理类型的一个加载者.第二个是要被代理对象的实现的接口列表,第三个是一个对象,这个对象要实现invocationhandler接口的invoke方法来执行你的方法.
--------------------------分界线-----------------------------
Cglib代理
1 package com.bxw.invocation; 2 3 import java.lang.reflect.Method; 4 5 import net.sf.cglib.proxy.Enhancer; 6 import net.sf.cglib.proxy.MethodInterceptor; 7 import net.sf.cglib.proxy.MethodProxy; 8 9 public class CglibProxy implements MethodInterceptor { 10 private Object o; 11 12 public Object getInstance(Object target){ 13 this.o = target; 14 Enhancer e = new Enhancer(); 15 e.setSuperclass(this.o.getClass()); 16 e.setCallback(this); 17 return e.create(); 18 } 19 @Override 20 public Object intercept(Object o, Method method , Object[] args, 21 MethodProxy methodProxy) throws Throwable { 22 System.out.println("-----before"+methodProxy.getSuperName()+"-----"); 23 System.out.println(method.getName()); 24 //方法、参数 25 Object o1 = methodProxy.invokeSuper(o, args); 26 System.out.println("-----after"+methodProxy.getSuperName()+"-----"); 27 return null; 28 } 29 30 }
getInstance用来获得代理类。
Object o1 = methodProxy.invokeSuper(o, args);注意这里是用invokeSuper方法而不是invoke方法。
1 package com.bxw.test; 2 3 import com.bxw.invocation.CglibProxy; 4 import com.bxw.service.UserService; 5 import com.bxw.serviceImpl.UserServiceImpl; 6 7 public class TestDemo2 { 8 public static void main(String[] args) { 9 CglibProxy cl = new CglibProxy(); 10 UserService u = (UserService) cl.getInstance(new UserServiceImpl()); 11 u.getAge(1); 12 u.getAge(1); 13 } 14 }