1.什么是代理模式
代理模式是面向对象编程中比较常见的设计模式。其目的就是避免用户直接接触实际的业务类而带来的不必要的麻烦,或者增强被代理类的功能而又不和被代理类的业务逻辑耦合。代理模式就像是给人穿上了一套“机械骨骼”,增强了人的身体机能,但是又可以随时脱掉,并不会像打了兴奋剂一样,进入容易再想出来就难了。
代理模式主要分为静态代理和动态代理两种,但是这两种代理模式有一个共同的特点就是被代理类一定要实现一个接口。不管是静态代理还是动态代理他们底层的实现方式都是实现被代理类的接口。
1.静态代理
静态代理是指我们在编写程序时,已经将“业务代理类”创建好了,它所代理的类已经是确定并创建好的,不管你用不用它,它就在那里等你
1.创建业务接口类
package com.hao.staticproxy.service;
public interface UserService {
public void createUser();
}
2.创建业务实现类
package com.hao.staticproxy.service.impl;
import com.hao.staticproxy.service.UserService;
class UserServiceImpl implements UserService {
@Override
public void createUser() {
System.out.println("创建用户");
}
}
3.创建业务代理类,并实现业务接口
package com.hao.staticproxy.service.impl;
import com.hao.staticproxy.service.UserService;
public class UserServiceProxyImpl implements UserService {
private UserServiceImpl userService = new UserServiceImpl();
@Override
public void createUser() {
System.out.println("前置增强操作");
userService.createUser();
System.out.println("后置增强操作");
}
}
4.测试调用,创建一个代理类对象,调用实现方法
3.动态代理
动态代理是指我们在编写程序时,利用java提供的java.lang.reflect.InvocationHandler接口,编写了一个动态的代理类,最终它的代理类是谁,是由调用它的有参构造器创建它时传入的对象类型决定的,所以我们就可以根据需求传入不同的对象来动态获取代理对象了。
1.创建动态代理处理器,并实现InvocationHandler接口和invoke方法
package com.hao.dynamicproxy.service.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxyServiceImpl implements InvocationHandler {
private Object proxyObject;
public DynamicProxyServiceImpl(Object proxyObject) {
super();
this.proxyObject = proxyObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理调用前");
Object invoke = method.invoke(proxyObject, args);
System.out.println("代理调用后");
return invoke;
}
}
2.测试调用,通过java.lang.reflect.Proxy下的newProxyInstance方法获取被代理对象
package com.hao.dynamicproxy.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.hao.dynamicproxy.service.DynamicRuleService;
import com.hao.dynamicproxy.service.DynamicUserService;
import com.hao.dynamicproxy.service.impl.DynamicProxyServiceImpl;
import com.hao.dynamicproxy.service.impl.DynamicRuleServiceImpl;
import com.hao.dynamicproxy.service.impl.DynamicUserServiceImpl;
public class DynamicProxyTest {
public static void main(String[] args) {
//1.获取想要被代理的对象
//测试对象1
DynamicUserServiceImpl proxyObject = new DynamicUserServiceImpl();
//2.通过被代理对象获取代理对象
Object createPorxy = createPorxy(proxyObject);
String createUser = ((DynamicUserService) createPorxy).createUser("qianghao");
System.out.println(createUser+"被创建了");
System.out.println("-----------------------------------------------------------");
//测试对象2
DynamicRuleServiceImpl proxyObject2 = new DynamicRuleServiceImpl();
//2.通过被代理对象获取代理对象
Object createPorxy2 = createPorxy(proxyObject2);
String createRule = ((DynamicRuleService) createPorxy2).createRule("全业务管理");
System.out.println("用户权限“"+createRule+"”被创建了");
}
//获取newProxyInstance代理对象创建的必要参数
public static Object createPorxy(Object proxyObject) {
//1.通过被代理对象获取其类加载器,和实现的全部接口
ClassLoader classLoader = proxyObject.getClass().getClassLoader();
Class<?>[] interfaces = proxyObject.getClass().getInterfaces();
//2.获取代理对象(被代理类的功能加强类,也就是动态处理器)
InvocationHandler dynamicProxyServiceImpl = new DynamicProxyServiceImpl(proxyObject);
//3.通过java提供的反射代理接口,调用newProxyInstance方法创建代理对象
Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, dynamicProxyServiceImpl);
return proxyInstance;
}
}
我们获取代理对象主要是通过这个方法,以下是方法参数的官方注释
* @param loader the class loader to define the proxy class
* @param interfaces the list of interfaces for the proxy class to implement
* @param h the invocation handler to dispatch method invocations to
Object proxyInstance = Proxy.newProxyInstance(loader, interfaces, h);