动态代理指的是通过一个代理对象来创建对象,然后在代理对象中进行各种需求的处理。相对于静态代理运行前编译,动态代理是在程序运行时,运用反射机制动态创建而成。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。源码下载
首先写一个日志代理类LogProxy来实现InvocationHandler。
package com.spriProxy.util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class LogProxy implements InvocationHandler {
//防止外部实例化LogProxy对象
private LogProxy(){}
//创建代理对象
private Object target;
//创建一个方法来生成对象,参数是要代理的对象,经过此方法参数对象变为代理对象
public static Object getInstance(Object oject){
//创建LogProxy对象
LogProxy logProxy = new LogProxy();
//设置代理对象
logProxy.target = oject;
//通过Proxy的方法创建代理对象,第一个参数代理对象的classloader,第二个参数代理对象实现的所有接口
//第三个参数实现InvocationHandler的对象
//result得到的就是代理对象
Object result = Proxy.newProxyInstance(oject.getClass().getClassLoader(),
oject.getClass().getInterfaces(), logProxy);
return result;
}
/**
* 生成代理对象后,不管代理对象使用什么方法,都会调用invoke的方法
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
//对日志添加的位置进行控制
if(method.getName().equals("addUser")){
Logger.info(Level.DEBUGE, "动态代理-->增加用户前");
}
Object object = method.invoke(target, args);
if(method.getName().equals("addUser")){
Logger.info(Level.INFO, "动态代理-->增加用户后");
}
return object;
}
}
在xml文件中将代理的dao注入
<bean id="userDynamicProxy" class="com.spriProxy.util.LogProxy" factory-method="getInstance">
<!-- userDaoImpl传递到getInstance(Object oject)中object -->
<constructor-arg ref="userDaoImpl"></constructor-arg>
</bean>
但是上述实现JDK的动态代理需要依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,如果需要代理可以使用cglib代理。