动态代理的作用
不修改原方法代码的基础上,实现方法增强,利于减少重复代码,提高开发效率,方便维护。
java动态代理实现方式
基于接口的动态代理
由jdk提供的Proxy类实现动态代理,使用此方法的限制:被代理类至少实现一个接口,否则无法实现。注意,使用基于接口的动态代理,其返回值应该是个接口对象。
代码:
public static void main(String[] args) {
final Producer producer = new Producer();//匿名内部类访问需要定义成final对象
producer.sale(10000);
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
producer.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("基于接口的动态代理实现:");
Object returnValue = null;
Integer money = (Integer) args[0];
if ("sale".equals(method.getName())){
returnValue = method.invoke(producer, money * 2);
}
return returnValue;
}
});
proxyProducer.sale(10000);
}
运行结果
基于子类的动态代理
由cglib提供的Enhancer类实现动态代理,使用此方法的限制:被代理类不能是final类,否则无法实现。注意,使用基于子类的动态代理,其返回值应该是个类对象。
代码:
public static void main(String[] args) {
final Producer producer = new Producer();//匿名内部类访问需要定义成final对象
producer.sale(10000);
//返回值为实体类类型
Producer cglibProducer= (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("基于子类的动态代理实现:");
Object returnValue = null;
Integer money = (Integer) args[0];
if ("sale".equals(method.getName())){
returnValue = method.invoke(producer, money * 2);
}
return returnValue;
}
});
cglibProducer.sale(10000);
}
如果出现如下异常,是因为方法增强后的返回值不匹配,该用接口就接口,改用类就用类。
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to com.laoye.proxy.Producer