目录
一、静态代码
定义一个接口如下:
public interface Flyable
{
void flight();
}
编写实现类如下:
public class Bird implements Flyable
{
public void flight()
{
System.out.println("Brid fly in the sky!");
}
}
创建实例,接口调用如下:
Flyable f = new Bird();
f.flight();
二、动态代码
Java标准库提供了一种动态代理(Dynamic Proxy)的机制:可以在运行期动态创建某个interface
的实例。
public class MainTest
{
public static void main(String[] args)
{
Flyable f = (Flyable) Proxy.newProxyInstance(
Flyable.class.getClassLoader(), // 传入ClassLoader
new Class[] { Flyable.class }, // 传入要实现的接口
(proxy, method, ars) -> // 传入处理调用方法的InvocationHandler
{
System.out.println(method);
if (method.getName().equals("flight"))
{
System.out.println("dynamic proxy, can fly too!");
}
return null;
});
f.flight();
}
}
从上述代码中可以发现,主要是用Proxy的newProxyInstance方法对这个interface生成一个代理对象。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader:选用的类加载器
interfaces:被代理的类所实现的接口,这个接口可以是多个。
h:绑定代理类的一个方法,public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
动态代理是通过Proxy
创建代理对象,主要是用反射来实现实例化的,然后将接口方法“代理”给InvocationHandler
完成的。
动态代理其实一般很少去手写,但是却经常使用到。在Spring项目中用的注解是动态代理最佳的落地点,例如依赖注入的@Bean、@Autowired,事务注解@Transactional等。