天天看點

一起研究 代理模式代理模式:

代理模式:

AOP的作用:不修改源碼的情況下,程式運作期間對方法進行功能增強

AOP的實作機制:動态代理

代理模式:在一個原有功能的基礎上添加新的功能。
分類:

靜态代理:要求代理類存在

動态代理:可以在程式運作時,根據被代理對象動态生成代理對象.

傳統的方式:核心代碼和服務代碼寫在一起:

try {
            System.out.println("開啟事務");
            System.out.println("執行核心業務代碼-------");
            System.out.println("送出事務");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("復原事務");
        } finally {
        }
           

1.靜态代理:

1.1 基于類的靜态代理:

要求: 繼承被代理的對象.

缺點:代理類隻能代理一個類

public class ProxyStudentService extends  StudentService {
    public  void main(String[] args) {
        try {
            System.out.println("開啟事務");
           super.coreCode();
            System.out.println("送出事務");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("復原事務");
        } finally {
        }
    }
}
           

1.2基于接口的靜态代理:

要求:代理類和被代理類實作同一個接口,代理類可以代理多個類,也可以有多個代理類(多重代理):

缺點: 代理對象和需要與目标對象實作一樣的接口,會産生很多的代理類,類太多,一旦接口增加方法,代理對象和被代理對象都要維護.

接口:

public interface IService  {
    void coreCode(); //需要增強的方法

}
           

代理類:

public class TranProxyService implements IService {
    private  IService  iService ;

    public TranProxyService(IService iService) {
        this.iService = iService;
    }

    @Override
    public void coreCode() {
        try {
            System.out.println("開啟事務");
           iService.coreCode();
            System.out.println("送出事務");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("復原事務");
        } finally {
        }
    }
}

           

一個代理類支援多個被代理對象:

public class TeamService implements IService {
    @Override
    public void coreCode() {
        System.out.println("teamService的核心代碼----------");
    }
}
           
public class TeacherService implements IService {
    @Override
    public void coreCode() {
        System.out.println("這是teacherService 核心代碼--------");
    }
}

           
TeacherService teacherService=new TeacherService();
        TranProxyService teachProxyService = new TranProxyService(teacherService);
        TranProxyService teamProxyService = new TranProxyService(teamService);
       teacherService.coreCode();
       teamProxyService.coreCode();     
           

多重代理:

TeamService target = new TeamService();
        TranProxyService tranProxyService = new TranProxyService(target);
        LogProxyService logProxyService =new LogProxyService(tranProxyService);
        logProxyService.coreCode();
           

1.3 提取切面代碼,作為AOP接口

public interface Aop {
    void before();
    void  after();
    void exception();
    void finall();
}
           
public class LogAop implements Aop {
    @Override
    public void before() {
        System.out.println("日志開始");
    }

    @Override
    public void after() {
        System.out.println("日志結束");

    }

    @Override
    public void exception() {
        System.out.println("日志異常");

    }

    @Override
    public void finall() {
        System.out.println("日志最終-------");

    }
}
           
public class MyProxyService implements  IService {

    private  IService iService;//被代理的對象
    private Aop myAop;//切面對象

    public MyProxyService(IService iService, LogAop logAop) {
        this.iService = iService;
        this.myAop = logAop;
    }

    @Override
    public void coreCode() {
        try {
            myAop.before();
            iService.coreCode();
            myAop.after();
        } catch (Exception e) {
            myAop.exception();
            e.printStackTrace();
        } finally {
            myAop.finall();
        }

    }
}
           
TeamService target = new TeamService();    //目标對象(被代理對象)
LogAop logAop = new LogAop();                   //日志切面對象
LogProxyService logProxyService = new LogProxyService(target, logAop); //産生代理對象
logProxyService.coreCode();                     //執行代理對象方法
           

2.動态代理:

2.1 基于jdk的動态代理:

final TeamService target = new TeamService();    //目标對象(被代理對象)

        IService proxyTeamService = (IService) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("before");
                Object res = method.invoke(target, objects);//這裡使用目标對象(被代理對象)
                System.out.println("after");
                return res;


            }
        });
        proxyTeamService.coreCode();
           

基于jdk 動态代理的缺點:

目标對象需要實作一個或者多個接口

2.1 CGLib子類代理:

CGLIB代理,可以在運作期間,在記憶體中建構一個子類對象,進而實作對目标對象的功能擴充.

final TeamService target = new TeamService();    //目标對象(被代理對象)
TeamService proxyService = (TeamService) Enhancer.create(target.getClass(), new MethodInterceptor() {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("before");
        Object invoke = methodProxy.invokeSuper(o, objects);
        System.out.println("after");
        return invoke;
    }
});

proxyService.coreCode();