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();
}
}
通過繼承的方式實作靜态代理
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實作動态代理
package com.mayikt.service;
public interface OrderService {
/**
* 共同抽象的方法
*/
void order();
}
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);
}
}
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>
package com.mayikt.service.impl;
import com.mayikt.service.OrderService;
public class OrderServiceImpl {
public void order() {
System.out.println("執行訂單業務邏輯代碼");
}
}
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;
}
}
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();
}
}