靜態(tài)代理
- 我們?cè)诓恍薷臉I(yè)務(wù)的情況下想要給它增加一些功能,這就需要使用代理模式。
- 我們不會(huì)在原有業(yè)務(wù)上直接修改,為了避免修改導(dǎo)致程序不可逆轉(zhuǎn)的破壞。
- 三種角色:抽象角色-接口、真實(shí)角色-實(shí)現(xiàn)類(lèi)和代理角色-代理類(lèi)。
- 真實(shí)角色和代理角色繼承的是同一個(gè)抽象角色接口!
業(yè)務(wù)接口類(lèi)?
負(fù)責(zé)抽象出業(yè)務(wù)需要的功能。
//抽象業(yè)務(wù)
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}
業(yè)務(wù)的實(shí)現(xiàn)類(lèi)
public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一個(gè)用戶(hù)");
}
@Override
public void delete() {
System.out.println("刪除了一個(gè)用戶(hù)");
}
@Override
public void update() {
System.out.println("修改了一個(gè)用戶(hù)");
}
@Override
public void query() {
System.out.println("查詢(xún)了一個(gè)用戶(hù)");
}
}
代理類(lèi)
假如我們現(xiàn)在要給業(yè)務(wù)增加一個(gè)新的功能-輸出日志功能,我們需要通過(guò)一個(gè)代理類(lèi)來(lái)實(shí)現(xiàn) ,而不是直接在舊業(yè)務(wù)上修改代碼。
我們?cè)黾右粋€(gè) log 方法(拓展功能),我們需要一個(gè) set 方法來(lái)使代理能夠通過(guò)舊的實(shí)現(xiàn)類(lèi)調(diào)用舊的業(yè)務(wù)。
//代理實(shí)現(xiàn)增刪改查
public class UserServiceProxy implements UserService{
UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
@Override
public void add() {
log("add");
userService.add();
}
@Override
public void delete() {
log("delete");
userService.delete();
}
@Override
public void update() {
log("update");
userService.update();
}
@Override
public void query() {
log("query");
userService.query();
}
public void log(String message){
System.out.println("使用了" + message + "方法");
}
}
測(cè)試
這樣我們的只需要給代理設(shè)置舊業(yè)務(wù)的實(shí)現(xiàn)類(lèi)就實(shí)現(xiàn)了業(yè)務(wù)的功能擴(kuò)展。
public class Client {
public static void main(String[] args) {
UserServiceImpl service = new UserServiceImpl();
UserServiceProxy proxy = new UserServiceProxy();
proxy.setUserService(service);
proxy.add();
}
}
動(dòng)態(tài)代理
- 動(dòng)態(tài)代理個(gè)靜態(tài)代理角色一樣(抽象角色-接口、真實(shí)角色-實(shí)現(xiàn)類(lèi)和代理角色-代理類(lèi))
- 動(dòng)態(tài)代理的代理類(lèi)是通過(guò)反射動(dòng)態(tài)生成的!
- 動(dòng)態(tài)代理按照實(shí)現(xiàn)可以分我:基于接口的 和 基于類(lèi)的動(dòng)態(tài)代理。
- 基于接口:JDK 動(dòng)態(tài)代理
- 基于類(lèi):cglib
- 需要了解兩個(gè)類(lèi):Proxy:代理、InvocationHandler:調(diào)用處理程序。
- 一個(gè)動(dòng)態(tài)代理類(lèi)就是一個(gè)接口!
- 一個(gè)動(dòng)態(tài)代理類(lèi)可以代理多個(gè)真實(shí)角色類(lèi),只需要繼承同一個(gè)業(yè)務(wù)接口即可。
- 使用動(dòng)態(tài)代理可以大大減少代碼量!因?yàn)樗褂昧朔瓷洌?/li>
Proxy:
Proxy 一共只有4個(gè)方法:
?
?
?InvocationHandler:
InvocationHandler是一個(gè)接口!
InvocationHandler 整個(gè)類(lèi)里只有一個(gè)方法:invoke方法。?
?動(dòng)態(tài)代理的實(shí)現(xiàn)
抽象角色
//抽象業(yè)務(wù)
public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}
真實(shí)角色
public class UserServiceImpl implements UserService {
@Override
public void add() {
System.out.println("增加了一個(gè)用戶(hù)");
}
@Override
public void delete() {
System.out.println("刪除了一個(gè)用戶(hù)");
}
@Override
public void update() {
System.out.println("修改了一個(gè)用戶(hù)");
}
@Override
public void query() {
System.out.println("查詢(xún)了一個(gè)用戶(hù)");
}
}
代理角色
使用 Object 作為抽象角色,這樣這一個(gè)代理類(lèi)就可以當(dāng)做工具類(lèi)來(lái)給任何真實(shí)角色進(jìn)行功能擴(kuò)展!文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-592899.html
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//代理處理程序
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setUserService(Object target) {
this.target = target;
}
//生成并得到代理類(lèi)
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
//處理代理實(shí)例,調(diào)用抽象接口的方法,并返回結(jié)果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//動(dòng)態(tài)代理的本質(zhì)就是使用反射機(jī)制實(shí)現(xiàn)!
fun1();
log(method.getName());
Object result = method.invoke(target, args);
fun2();
return result;
}
public void fun1(){
System.out.println("擴(kuò)展功能1");
}
public void fun2(){
System.out.println("擴(kuò)展功能2");
}
public void log(String message){
System.out.println("執(zhí)行了" + message + "方法");
}
}
測(cè)試
public class Client {
public static void main(String[] args) {
//真實(shí)角色
UserServiceImpl userService = new UserServiceImpl();
//代理角色
ProxyInvocationHandler handler = new ProxyInvocationHandler();
//設(shè)置要代理的真實(shí)對(duì)象
handler.setUserService(userService);
//動(dòng)態(tài)生成代理類(lèi)
UserService proxy = (UserService) handler.getProxy();
proxy.add();
proxy.delete();
}
}
輸出結(jié)果:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-592899.html
擴(kuò)展功能1
執(zhí)行了add方法
增加了一個(gè)用戶(hù)
擴(kuò)展功能2
擴(kuò)展功能1
執(zhí)行了delete方法
刪除了一個(gè)用戶(hù)
擴(kuò)展功能2
到了這里,關(guān)于代理模式【靜態(tài)代理和動(dòng)態(tài)代理實(shí)現(xiàn)業(yè)務(wù)功能擴(kuò)展】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!