java动态代理的原理
在许多mvc框架中,经常用到注解来实现面向切面(aop)的编程。面向切面编程,可以对业务逻辑中各部分进行分离,提高程序的重用性,降低各逻辑业务部分的耦合度。
jdk中利用反射原理使用Proxy类对对象进行代理。
jdk动态代理的应用前提是,目标类基于统一的接口。
接口类:
public interface Service { public void doService(); }
继承Service的实现类:
1 public class ServiceImpl1 implements Service { 2 @Override 3 public void doService() { 4 System.out.println("impl 1 do the service...."); 5 6 } 7 } 8 public class ServiceImpl2 implements Service { 9 @Override 10 public void doService() { 11 System.out.println("impl 2 do the service..."); 12 } 13 }
代理工厂类的getService方法,传入参数是被代理的service的class。创建InvocationHandler类对象,对被代理对象的方法进行处理。
1 public <T extends Service> T getService(Class<T> clazz) { 2 String simpleName = clazz.getSimpleName(); 3 String implName = getImplName(simpleName); 4 try { 5 final T service = (T) Class.forName(implName).newInstance(); 6 T froxyService = (T) Proxy.newProxyInstance(service.getClass().getClassLoader(), 7 service.getClass().getInterfaces(), new InvocationHandler() { 8 9 @Override 10 public Object invoke(Object proxy, Method method, Object[] args) 11 throws Throwable { 12 System.out.println("do something before proxy method..."); 13 Object obj = method.invoke(service, args); 14 System.out.println("do something after proxy method..."); 15 return obj; 16 } 17 }); 18 return froxyService; 19 } catch (Exception e) { 20 e.printStackTrace(); 21 throw new RuntimeException(); 22 } 23 }
测试类和结果:
1 public class ProxyTest { 2 public static void main(String[] args) { 3 Factory factory = new Factory(); 4 Service impl1 = new ServiceImpl1(); 5 Service proxyImpl1 = factory.getService(impl1.getClass()); 6 proxyImpl1.doService(); 7 Service impl2 = new ServiceImpl2(); 8 Service proxyImpl2 = factory.getService(impl2.getClass()); 9 proxyImpl2.doService(); 10 } 11 } 12 13 结果是: 14 do something before proxy method... 15 impl 1 do the service.... 16 do something after proxy method... 17 do something before proxy method... 18 impl 2 do the service... 19 do something after proxy method...