一、什么是代理模式
简单说即是在不改变源码的情况下,实现对目标对象的功能扩展。
二、动态代理
2.1、被代理的接口
public interface Demo {
void test1();
void test2();
}
2.2、被代理的对象(实现了被代理接口的对象)
public class DemoImpl implements Demo {
@Override
public void test1() {
System.out.println("=====执行test1()=======");
}
@Override
public void test2() {
System.out.println("=====test2()=======");
}
}
2.3、代理对象
public class MyHandler implements InvocationHandler {
//代理对象
private Object targer;
public MyHandler(Object targer) {
this.targer = targer;
}
@Override
public Object invoke(Object obj, Method method, Object[] objects) throws Throwable {
System.out.println("==代理对象执行额外业务================");
//记录日志、权限控制、事务处理 ... ...
return method.invoke(targer,objects);//代理对象执行被代理对象的方法
}
public static void main(String[] args){
Demo targer = new DemoImpl(); //(真实)被代理对象
MyHandler handler = new MyHandler(targer); //代理对象
Demo proxyDemo = (Demo) Proxy.newProxyInstance(MyHandler.class.getClassLoader(),
new Class[]{Demo.class},handler);//使用反射生成一个被代理的对象
proxyDemo.test1();
proxyDemo.test2();
}
}
三、静态代理
3.1、被代理的接口
public interface Demo {
void test1();
}
3.2、被代理的对象
public class DemoImpl implements Demo {
@Override
public void test1() {
System.out.println("=====执行test1()=======");
}
}
3.3、代理对象
public class DemoProxy implements Demo{
private Demo demo;
public DemoProxy(Demo demo) {
this.demo = demo;
}
@Override
public void test1() {
System.out.println("该方法使用静态代理之前执行。。。");
demo.test1();
System.out.println("该方法使用静态代理之后执行。。。");
}
public static void main(String[] args) {
Demo demo = new DemoImpl();
Demo demoProxy = new DemoProxy(demo);
demoProxy.test1();
}
}
四、Cglib代理
4.1、被代理的对象
public class Demo {
public void test1() {
System.out.println("=====执行test1()=======");
}
}
4.2、Cglib代理对象工厂
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/** Cglib子类代理工厂
* 创 建 时 间: 2019/10/20
* 版 本: V1.0
* 作 者: qixin
* 版 权 所 有: 版权所有(C)2019-2029
*/
public class ProxyFactory implements MethodInterceptor {
private Object target; // 维护目标对象
public ProxyFactory(Object target) {
this.target = target;
}
// 给目标对象创建一个代理对象
public Object getProxyInstance(){
Enhancer en = new Enhancer(); //1.工具类
en.setSuperclass(target.getClass()); //2.设置父类
en.setCallback(this); //3.设置回调函数
return en.create(); //4.创建子类(代理对象)
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("向观众问好");
//执行目标对象的方法
Object returnValue = method.invoke(target, objects);
System.out.println("谢谢大家");
return returnValue;
}
public static void main(String[] args) {
Demo demo = new Demo(); //目标对象
//代理对象
Demo proxy = (Demo)new ProxyFactory(demo).getProxyInstance();
proxy.test1(); //执行代理对象的方法
}
}
五、动态代理使用场景:权限校验
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface PrivilegeInfo {
String value(); //权限名称
}
public interface OrderService {
// 添加订单
@PrivilegeInfo("生成订单")
public void add(User user, Order order) throws PrivilegeException,
Exception;
// 根据用户查找订单
@PrivilegeInfo("查看订单")
public List<Order> find(User user) throws PrivilegeException, Exception;
// 根据id删除订单
public void delete(String id) throws Exception;
}
public class OrderServiceFactory {
private static OrderService service = new OrderServiceImpl();
public static OrderService getInstance() {
return (OrderService) Proxy.newProxyInstance(
service.getClass().getClassLoader(),
service.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args ) throws IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
// 1.判断是否有注解
if (method.isAnnotationPresent(PrivilegeInfo.class)) {
// 2。得到注册对象
PrivilegeInfo pif = method.getAnnotation(PrivilegeInfo.class);
// 3.得到权限名称
String pname = pif.value();
// 4.得到用户
User user = (User) args[0];
if (user == null) {
throw new PrivilegeException();
}
// 5.根据用户查询是否具有权限
PrivilegeDao pdao = new PrivilegeDao();
if (!pdao.checkPrivilege(user.getRole(), pname)) {
throw new PrivilegeException(); // 抛出权限不足异常
}
}
return method.invoke(service, args);
}
});
}
}
// 使用
// 2.调用OrderService中查询订单操作
OrderService service = OrderServiceFactory.getInstance();
List<Order> orders = service.find(user);