所谓动态代理其实就是运行期,动态的增强了目标对象的执行方法。
jdk的动态代理
JDK的动态代理是按照接口代理的。接口中没有的方法,无法代理。
其实JDK动态代理就是JDK自己帮我们实现类那个静态代理中的代理类。
jdk的Proxy类提供了一个静态方法,用于获取动态代理类的实例。
这个静态方法:static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
返回目标类的一个代理对象实例。
参数1:目标类的类加载器
参数2:目标类实现的所有接口的数组
参数3:增强处理器,需要我们自己实现
例子:准备一个动态代理工厂,用于功能增强(用于给某个方法前后添加其他方法)
package com.quail.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
private Object target;//被代理的目标对象
// 使用构成方法初始化目标对象
public ProxyFactory(Object target){
this.target = target;
}
// 返回代理对象
public Object getObject(){
// 传入相应的参数
Class clazz = target.getClass();
// 使用匿名内部类直接实现InvocationHandler
Object obj = Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), new InvocationHandler() {
// proxy:代理实例;method:被增强的方法;args:被增强的方法的参数列表;return:被增强方法的返回值
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("目标方法前功能增强");
Object result = method.invoke(target, args);
System.out.println("目标方法后功能增强");
return result;
}
});
return obj;
}
}
实体类和接口:
public interface UserDao {
int save(String name);
}
public class UserDaoImpl implements UserDao {
public int save(String name) {
System.out.println("我的名字是:"+name);
return 1;
}
}
测试类:
package com.quail.test;
import com.quail.dao.UserDao;
import com.quail.dao.impl.UserDaoImpl;
import com.quail.proxy.ProxyFactory;
import org.junit.Test;
public class ProxyTest {
@Test
public void testJDKProxy(){
// 准备目标对象
UserDaoImpl userDao = new UserDaoImpl();
// 使用工厂创建代理对象
ProxyFactory proxyFactory = new ProxyFactory(userDao);
// 获取代理对象,必须是接口类型
UserDao dao = (UserDao) proxyFactory.getObject();
dao.save("quail");
}
}
Spring的动态代理
Spring实现动态代理其实通过两种方式:
- 一种是JDK的动态代理方式,使用Proxy类的静态方法newProxyInstance()
- 另一种是CGLib包的动态代理方式。这种方式可以代理接口中没有的方法。原因:CGLib增强一个方法是使用继承实现的。CGLib可以看做是JDK动态proxy的一个升级,区别:不光可以代理有接口的对象,还可以代理没有接口的对象。 ```java package com.quail.proxy;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.InvocationHandler;
import java.lang.reflect.Method;
public class CGLibProxyFactory { private Object target;//目标对象
public CGLibProxyFactory(Object target){this.target=target;}
public Object getObject(){
// 直接创建一个增强器对象
Enhancer enhancer = new Enhancer();
// 设置父类类型
enhancer.setSuperclass(target.getClass());
// 设置处理器
enhancer.setCallback(new InvocationHandler() {
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
System.out.println("目标方法前的增强");
Object invoke = method.invoke(target, objects);
System.out.println("目标方法后的增强");
return invoke;
}
});
return enhancer.create();//创建代理对象并且返回
}
}
```