1.什么是代理模式? 为对象提供一种代理以控制对这个对象的访问。代理模式相当于:中介或者经纪人 ,代理类可以在被代理类的基础之上增加功能(扩展功能),比如日志记录和权限控制 ,这样被代理类隐藏起来了,比较安全。
1.代理模式实现方式有哪些? 静态代理和动态代理 2.静态代理是:需要程序员人为创建好代理类,缺点;如果被代理类很多的话,需要手写很多个代理类,代码会变得非常冗余。 3.静态代理实现方式有哪些? 1.通过继承2.实现接口
1.通过实现接口方式实现静态代理
1.定义共同接口
package com.mayikt.service;
public interface OrderService {
/**
* 共同抽象的方法
*/
void order();
}
2.定义被代理类实现共同的接口
package com.mayikt.service.impl;
import com.mayikt.service.OrderService;
public class OrderServiceImpl implements OrderService {
public void order() {
System.out.println("执行订单业务逻辑代码");
}
}
3.手写代理类OrderServiceProxy
package com.mayikt.service.proxy;
import com.mayikt.service.OrderService;
import com.mayikt.service.impl.OrderServiceImpl;
public class OrderServiceProxy implements OrderService {
/**
* 被代理对象
*/
private OrderService orderService;
public OrderServiceProxy(OrderService orderService) {
this.orderService = orderService;
}
public void order() {
System.out.println(">>>打印订单日志开始");
orderService.order();
System.out.println(">>>打印订单日志结束");
}
}
4.测试
package com.mayikt.service;
import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
import com.mayikt.service.impl.OrderServiceImpl;
import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
import com.mayikt.service.proxy.OrderServiceProxy;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Client {
public static void main(String[] args) {
OrderService orderService = new OrderServiceProxy(new OrderServiceImpl());
orderService.order();
}
}
通过继承的方式实现静态代理
1.定义共同接口
package com.mayikt.service;
public interface OrderService {
/**
* 共同抽象的方法
*/
void order();
}
2.定义被代理类
package com.mayikt.service.impl;
import com.mayikt.service.OrderService;
public class OrderServiceImpl implements OrderService{
public void order() {
System.out.println("执行订单业务逻辑代码");
}
}
3.手写代理类
package com.mayikt.service.proxy;
import com.mayikt.service.OrderService;
import com.mayikt.service.impl.OrderServiceImpl;
public class OrderServiceProxy extends OrderServiceImpl {
public void order() {
System.out.println(">>>打印订单日志开始");
super.order();// 执行父类的order 方法OrderServiceImpl
System.out.println(">>>打印订单日志结束");
}
}
4、测试
package com.mayikt.service;
import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
import com.mayikt.service.impl.OrderServiceImpl;
import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
import com.mayikt.service.proxy.OrderServiceProxy;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Client {
public static void main(String[] args) {
OrderService orderService = new OrderServiceProxy();
orderService.order();
}
}
动态代理
1.动态代理:不需要关心代理类, jvm运行的时候自动创建代理类,不需要手动创建。 2.动态代理实现方式有哪些? jdk动态代理和cglib原理 3.jdk动态代理:jdk动态生成的代理类都是实现接口形式,所以被代理类必须实现接口(通过反射的方式实现) cglib代理:通过asm字节码技术实现动态生成代理类,运行时动态的生成一个被代理类的子类 4.jdK动态代理要求被代理的类必须实现接口,当需要被代理的类没有实现接口时cglib代理是一个很好的选择 5.spring默认会使用JDK的动态代理,但是如果目标对象没有实现接口,则默认会采用CGLIB代理;
jdk实现动态代理
1.定义共同接口
package com.mayikt.service;
public interface OrderService {
/**
* 共同抽象的方法
*/
void order();
}
2.定义被代理类实现共同的接口
package com.mayikt.service.impl;
import com.mayikt.service.OrderService;
public class OrderServiceImpl implements OrderService {
public void order() {
System.out.println("执行订单业务逻辑代码");
}
}
3.创建生成动态代理类的类:JdkInvocationHandler
package com.mayikt.service.jdk.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkInvocationHandler implements InvocationHandler {
/**
* 被代理类对象 目标代理对象
*/
private Object target;
public JdkInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行方法前打印日志
System.out.println(">>>jdk打印订单日志开始:proxy:"+proxy.getClass().toString());
Object reuslt = method.invoke(target, args);// java的反射机制执行方法 执行目标对象的方法
//执行方法后打印日志
System.out.println(">>>jdk打印订单日志结束");
return reuslt;
}
/**
* 使用jdk动态代理创建代理类
*
* @param <T>
* @return
*/
public <T> T getProxy() {
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}
4.测试
package com.mayikt.service;
import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
import com.mayikt.service.impl.OrderServiceImpl;
import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
import com.mayikt.service.proxy.OrderServiceProxy;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Client {
public static void main(String[] args) {
// 1.使用jdk动态代理
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");//可以动态生成.class文件
OrderService proxy = new JdkInvocationHandler(new OrderServiceImpl()).getProxy();
proxy.order();
}
}
使用cglib实现动态代理
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.12</version>
</dependency>
2.定义被代理类
package com.mayikt.service.impl;
import com.mayikt.service.OrderService;
public class OrderServiceImpl {
public void order() {
System.out.println("执行订单业务逻辑代码");
}
}
3.创建生成动态代理类的类:CglibMethodInterceptor
package com.mayikt.service.cglib.proxy;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibMethodInterceptor implements MethodInterceptor {
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println(">>>>cglib日志收集开始....");
Object reuslt = proxy.invokeSuper(obj, args);
System.out.println(">>>>cglib日志收集结束....");
return reuslt;
}
}
4.测试
package com.mayikt.service;
import com.mayikt.service.cglib.proxy.CglibMethodInterceptor;
import com.mayikt.service.impl.OrderServiceImpl;
import com.mayikt.service.jdk.proxy.JdkInvocationHandler;
import com.mayikt.service.proxy.OrderServiceProxy;
import net.sf.cglib.core.DebuggingClassWriter;
import net.sf.cglib.proxy.Enhancer;
public class Client {
public static void main(String[] args) {
// 使用cglib动态代理
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\code");//可以动态生成class文件
CglibMethodInterceptor cglibMethodInterceptor = new CglibMethodInterceptor();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderServiceImpl.class);
enhancer.setCallback(cglibMethodInterceptor);
OrderServiceImpl orderServiceImpl = (OrderServiceImpl) enhancer.create();
orderServiceImpl.order();
}
}