动态代理:在程序运行时,运用反射机制动态创建代理对象。
为了弥补静态代理在开发过程中需要创建过多的代理的缺点,我们可以通过一个代理类完成生成全部代理类的功能,这种方式就是动态代理。
jdk动态代理
下面介绍一下jdk中关于代理的一个接口和一个类:
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类。
Proxy类:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
loader:类加载器
interfaces:得到全部的接口
h:得到InvocationHandler接口的子类实例
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
实例:
MyInvocationHandler.java(动态代理类)
public class MyInvocationHandler implements InvocationHandler{
private Object obj;
public void setObj(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = method.invoke(obj, args);
maintance();
return result;
}
private void maintance(){
System.out.println("维护");
}
}
UserService接口(抽象接口)
public interface UserService {
public void save();
}
UserServiceImpl .java(真实对象)
public class UserServiceImpl implements UserService{
@Override
public void save() {
System.out.println("保存成功啦");
}
}
Demo.java(测试类)
public class Demo {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
MyInvocationHandler handler = new MyInvocationHandler();
handler.setObj(userService);
UserService usi = (UserService) Proxy.newProxyInstance(
Demo.class.getClassLoader(),
userService.getClass().getInterfaces(),
handler);
usi.save();
}
}
有一点要注意,也就是说再jdk中动态代理要依靠接口来实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。
cglib动态代理
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
示例代码:
UserServiceImpl.java
public class UserServiceImpl{
public void save() {
System.out.println("保存成功啦");
}
}
MyCglibProxy.java
public class MyCglibProxy implements MethodInterceptor{
private Object target;
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("before");
Object result = proxy.invokeSuper(obj, args);
System.out.println("after");
return result;
}
}
Demo.java
public class Demo {
public static void main(String[] args) {
MyCglibProxy myCglibProxy = new MyCglibProxy();
UserServiceImpl userService = (UserServiceImpl) myCglibProxy.getInstance(new UserServiceImpl());
userService.save();
}
}