1、靜態代理
1.1靜態代理的代理類和和被代理的類都要維護一個共同的接口。
public interface IUserDao {
void save();
}
1.2被代理的類,目標對象
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("-----已經保存數據!!!------");
}
}
1.3代理對象
public class UserDaoProxy implements IUserDao{
// 接收保存目標對象
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target = target;
}
@Override
public void save() {
System.out.println("開始事務...");
target.save(); // 執行目標對象的方法
System.out.println("提交事務...");
}
}
1.4測試類
public class App {
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
// 代理
IUserDao proxy = new UserDaoProxy(target);
proxy.save(); // 執行的是,代理的方法
}
}
2、動態代理
2.1同樣的,動態代理也需要完成一個接口。(同上)
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("開啟事務");
// 執行目標對象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事務");
return returnValue;
}
});
}
}
2.4測試類
public class App {
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
System.out.println(target.getClass());
// 給目標對象,創建代理對象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
System.out.println(proxy.getClass());
// 執行方法 【代理對象】
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;
}
// 給目標對象創建代理對象
public Object getProxyInstance(){
//1. 工具類
Enhancer en = new Enhancer();
//2. 設置父類
en.setSuperclass(target.getClass());
//3. 設置回調函數
en.setCallback(this);
//4. 創建子類(代理對象)
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("開始事務.....");
// 執行目標對象的方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事務.....");
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());
// 執行代理對象的方法
proxy.save();
}
}