輕松掌握Java代理模式
和大家一起聊一聊java代理模式
1、靜態(tài)代理
1.1靜態(tài)代理的代理類和和被代理的類都要維護一個共同的接口。
public interface IUserDao {
void save();
}
1.2被代理的類,目標對象
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----已經(jīng)保存數(shù)據(jù)!?。?-----");
}
}
1.3代理對象
public class UserDaoProxy implements IUserDao{
// 接收保存目標對象
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target = target;
}
@Override
public void save() {
System.out.println("開始事務(wù)...");
target.save(); // 執(zhí)行目標對象的方法
System.out.println("提交事務(wù)...");
}
}
1.4測試類
public class App {
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
// 代理
IUserDao proxy = new UserDaoProxy(target);
proxy.save(); // 執(zhí)行的是,代理的方法
}
}
2、動態(tài)代理
2.1同樣的,動態(tài)代理也需要完成一個接口。(同上)
2.2目標對象也是相同的。
2.3只是在代理對象上有所不同
public class ProxyFactory {
// 維護一個目標對象
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
// 給目標對象,生成代理對象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("開啟事務(wù)");
// 執(zhí)行目標對象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事務(wù)");
return returnValue;
}
});
}
}
2.4測試類
public class App {
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
System.out.println(target.getClass());
// 給目標對象,創(chuàng)建代理對象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
// 執(zhí)行方法 【代理對象】
proxy.save();
}
}
3、cglib代理
3.1cglib代理不需要完成接口,只需要寫被代理的類和代理類即可,此處被代理類同1.2,所以不再編寫。
3.2代理類有所不同,用到cglib代理模式需要引用spring的核心框架包。
public class ProxyFactory implements MethodInterceptor{
// 維護目標對象
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
// 給目標對象創(chuàng)建代理對象
public Object getProxyInstance(){
//1. 工具類
Enhancer en = new Enhancer();
//2. 設(shè)置父類
en.setSuperclass(target.getClass());
//3. 設(shè)置回調(diào)函數(shù)
en.setCallback(this);
//4. 創(chuàng)建子類(代理對象)
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("開始事務(wù).....");
// 執(zhí)行目標對象的方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事務(wù).....");
return returnValue;
}
}
3.3測試類
public class App {
public static void main(String[] args) {
// 目標對象
UserDao target = new UserDao();
System.out.println(target.getClass());
// 代理對象
UserDao proxy = (UserDao) new ProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
// 執(zhí)行代理對象的方法
proxy.save();
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Mybatis基于MapperScan注解的動態(tài)代理加載機制詳解
這篇文章主要介紹了Mybatis基于MapperScan注解的動態(tài)代理加載機制,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧2023-01-01
IDEA創(chuàng)建Maven項目一直顯示正在加載的問題及解決
這篇文章主要介紹了IDEA創(chuàng)建Maven項目一直顯示正在加載的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12

