所谓动态代理其实就是运行期,动态的增强了目标对象的执行方法。
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();// 使用匿名内部类直接实现InvocationHandlerObject 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 {@Testpublic 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();//创建代理对象并且返回}
}
```
