1. 程式人生 > 其它 >靜態代理,動態代理,AOP

靜態代理,動態代理,AOP

靜態代理:

public interface IUser {
    //儲存使用者
    void save();
}
public class IUserImpl implements IUser{
    @Override
    public void save() {
        System.out.println("模擬儲存使用者");
    }
}
//靜態代理類,要與目標物件(IUserImpl)實現相同的介面
public class UserProxy implements IUser{

    private IUser target = new IUserImpl();

    @Override
    
public void save() { System.out.println("代理操作: 開啟事務..."); target.save(); // 執行目標物件的方法 System.out.println("代理操作:提交事務..."); } public static void main(String[] args) { IUser proxy = new UserProxy(); proxy.save(); } }

執行結果:

 

靜態代理缺點: 如果增加一個方法,除了實現類需要實現這個方法外,所有的代理類也要實現此方法。增加了程式碼的維護成本。那麼要如何解決呢?答案是使用動態代理。

動態代理:

介面:

package com.seeyii.web.yangkun.dynamicProxy;

public interface IVehicle {
void behavior();
}

實現類:

package com.seeyii.web.yangkun.dynamicProxy;

/**
 * @PackageName:com.seeyii.web.yangkun.dynamicProxy
 * @Description:
 * @Author 楊坤
 * @Date:2022/4/21 14:17
 */
public class Car implements IVehicle {
    @Override
    
public void behavior() { System.out.println("開汽車"); } }

呼叫處理類:

package com.seeyii.web.yangkun.dynamicProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @PackageName:com.seeyii.web.yangkun.dynamicProxy
 * @Description:
 * @Author 楊坤
 * @Date:2022/4/21 14:30
 */
public class VehicleInvacationHandler<T> implements InvocationHandler {
    //被代理的物件
    private T target;
    public VehicleInvacationHandler(T target){
        this.target=target;
    }
 /*
  * @Author 楊坤
  * @Date 14:34 2022/4/21
  * proxy 代表動態代理物件
  * method 代表正在執行的方法
  * args 代表呼叫目標方法時傳入的實參
  **/
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("---------before-------");
        Object invoke = method.invoke(target, args);
        System.out.println("---------after-------");
        return invoke;
    }
}

啟動類:

package com.seeyii.web.yangkun.dynamicProxy;

import java.lang.reflect.Proxy;

public class App {
    public static void main(String[] args) {
        IVehicle car = new Car();
        IVehicle vehicle = (IVehicle)Proxy.newProxyInstance(car.getClass().getClassLoader(), Car.class.getInterfaces(), new VehicleInvacationHandler(car));
        vehicle.behavior();
//
vehicle.behavior()會呼叫 VehicleInvacationHandler的invoke方法,invoke方法通過反射呼叫被代理類的對應方法
} }

執行結果:

 

 

 


如果被代理的類沒有實現介面,可以用CGLib方式實現動態代理

AOP:

package com.seeyii.web.yangkun.aop;

import com.seeyii.web.yangkun.dynamicProxy.Car;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

@Aspect
@Component
public class AopConfig {

    @Pointcut("execution( * com.seeyii.web.*.controller..*(..))")
    public void pointCut() {
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoin) {
        System.out.println("前置處理");
        Object obj = null;
        try {
//執行目標方法
            obj = joinPoin.proceed();
        System.out.println("後置處理");
} catch (Throwable throwable) { throwable.printStackTrace(); } return obj; } }