所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。
java动态代理主要是使用 java.lang.reflect
包中的两个类。
InvocationHandler类
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy是代理类,method是被代理的方法,args是被代理方法的参数。此方法由代理类实现。
Proxy类
protected Proxy(InvocationHandler h)
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
动态代理其实是在运行时生成class,所以,必须为其提供一组interface,然后告诉他class已经实现了这些interface,而且在生成Proxy的时候,必须给他提供一个handler,让他来接管实际的工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
public class CreateProxy implements InvocationHandler { private Object target;
public Object create(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("==> 开始代理 <=="); Object invoke = method.invoke(target, args); System.out.println("==> 结束代理 <=="); return invoke; } }
|
1 2 3 4 5 6 7 8 9
|
public class Person implements Runnable { @Override public void run() { System.out.println("核心业务"); } }
|
1 2 3 4 5 6 7 8
| public class MainClass { public static void main(String[] args) { CreateProxy createProxy = new CreateProxy(); Runnable person = new Person(); Runnable proxy = (Runnable) createProxy.create(person); proxy.run(); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public class Person implements Runnable, Consumer<String> { @Override public void run() { System.out.println("核心业务"); }
@Override public void accept(String s) { System.out.println("另一个核心业务:" + s); } }
|
1 2 3 4 5 6 7 8 9 10 11
| public class MainClass { public static void main(String[] args) { CreateProxy createProxy = new CreateProxy(); Person person = new Person(); Object proxy = createProxy.create(person); Runnable runnableProxy = (Runnable) proxy; runnableProxy.run(); Consumer consumerProxy = (Consumer) proxy; consumerProxy.accept("核心业务"); } }
|
动态代理应用:AOP框架的简单实现
1 2 3 4 5 6 7
| public class Message implements Consumer<String> { private List<String> list = new ArrayList<>(); @Override public void accept(String s) { list.add(s); } }
|
1 2 3 4
| public interface Advice { void beforeAdvice(); void afterAdvice(); }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public class LogAdvice implements Advice { @Override public void beforeAdvice() { System.out.println("start time:" + System.currentTimeMillis()); }
@Override public void afterAdvice() { System.out.println("end time:" + System.currentTimeMillis()); } }
|
1 2 3
| bean.target=Message bean.advice=LogAdvice bean=ProxyFactoryBean
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class ProxyFactoryBean implements InvocationHandler { private Object target; private Advice advice; public Object getProxy() { return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.beforeAdvice(); Object obj = method.invoke(target, args); advice.afterAdvice(); return obj; } public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } public Advice getAdvice() { return advice; } public void setAdvice(Advice advice) { this.advice = advice; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public class BeanFactory { private Properties prop = new Properties(); public BeanFactory(InputStream in) { try { prop.load(in); } catch (IOException e) { e.printStackTrace(); } } public Object getBean(String name) { String className = prop.getProperty(name); Object bean = null; try { Class<?> aClass = Class.forName(className); bean = aClass.newInstance(); Object target = Class.forName(prop.getProperty(name.concat(".target"))).newInstance(); Object advice = Class.forName(prop.getProperty(name.concat(".advice"))).newInstance(); BeanInfo beanInfo = Introspector.getBeanInfo(aClass); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { String propertyName = propertyDescriptor.getName(); Method writeMethod = propertyDescriptor.getWriteMethod(); if ("target".equals(propertyName)) { writeMethod.invoke(bean, target); } else if ("advice".equals(propertyName)) { writeMethod.invoke(bean, advice); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IntrospectionException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return bean; } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| public class MainClass { public static void main(String[] args) { InputStream in = ClassLoader.getSystemResourceAsStream("bean.properties"); BeanFactory beanFactory = new BeanFactory(in); ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean) beanFactory.getBean("bean"); Consumer<String> proxy = (Consumer<String>) proxyFactoryBean.getProxy(); proxy.accept("Tom"); } }
|