AOP底層實(shí)現(xiàn)

AOP底層實(shí)現(xiàn)

  • Spring在運(yùn)行期,生成動態(tài)代理對象,不需要特殊的編輯器
  • Sping AOP的底層就是通過JDK動態(tài)代理或者CGLib動態(tài)代理技術(shù)為目標(biāo)Bean執(zhí)行橫向織入
    1. 若目標(biāo)對象實(shí)現(xiàn)了若干接口,Spring使用JDK的java.lang.reflect.Proxy類代理
    2. 諾目標(biāo)對象沒有實(shí)現(xiàn)任何接口,Spring使用CGLib庫生成目標(biāo)對象的子類
      程序中應(yīng)優(yōu)先對接口創(chuàng)建代理,便于程序解耦維護(hù)=>面向接口編程規(guī)范
      標(biāo)記為final的方法,不能被代理,因?yàn)闊o法重寫覆蓋
  1. JDK動態(tài)代理,是針對接口生成子類,接口中方法不能使用final修飾
  2. CGLib是針對目標(biāo)類繼承子類,因此類或方法不能使用final修飾
    另外Spring只支持方法連接點(diǎn),不提供屬性連接

JDK動態(tài)代理

//MyJDKProxy
public class MyJDKProxy implements InvocationHandler {
    private UserDao userDaoimpl;

    public MyJDKProxy(UserDao userDaoimpl) {
        this.userDaoimpl = userDaoimpl;
    }

    public Object createProxy(){
        Object proxy = Proxy.newProxyInstance(userDaoimpl.getClass().getClassLoader(), userDaoimpl.getClass().getInterfaces(), this);
        return proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("權(quán)限驗(yàn)證代碼");
            return method.invoke(userDaoimpl, args);
        }
        return method.invoke(userDaoimpl, args);
    }
}

//UserDaoImpl
public class UserDaoImpl implements UserDao {
    @Override
    public void save(User user) {
        System.out.println("保存用戶");
    }

    @Override
    public void update(User user) {
        System.out.println("修改用戶");
    }

    @Override
    public void findAll() {
        System.out.println("查詢用戶");
    }

    @Override
    public void delete(Long id) {
        System.out.println("刪除用戶");
    }
}

//Proxy_Test
public class Proxy_Test {
    @Test
    public void myJDKProxy(){
        UserDao userDaoImpl = new UserDaoImpl();

        UserDao proxy = (UserDao) new MyJDKProxy(userDaoImpl).createProxy();
        proxy.save(new User());
    }
}

Cglib動態(tài)代理

//在使用CgLib時(shí)需要導(dǎo)入Spring基礎(chǔ)包
//MyCglib
public class MyCglib implements MethodInterceptor {
    private ProductDao productDaoImpl;

    public MyCglib(ProductDao productDaoImpl) {
        this.productDaoImpl = productDaoImpl;
    }

    public Object createProxy(){
        //1.創(chuàng)建核心對象
        Enhancer enhancer = new Enhancer();
        //2.設(shè)置父類
        enhancer.setSuperclass(productDaoImpl.getClass());
        //3.設(shè)置回調(diào)方法
        enhancer.setCallback(this);
        //4.創(chuàng)建代理對象
        Object proxy = enhancer.create();
        return proxy;
    }

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if("save".equals(method.getName())){
            System.out.println("權(quán)限驗(yàn)證中...");
            return methodProxy.invoke(productDaoImpl, args);
        }
        return methodProxy.invoke(productDaoImpl, args);
    }
}


//ProductDaoImlp
public class ProductDaoImlp implements ProductDao {
    @Override
    public void save(Product Product) {
        System.out.println("保存");
    }

    @Override
    public void update(Product Product) {
        System.out.println("修改");
    }

    @Override
    public void findAll() {
        System.out.println("查詢");
    }

    @Override
    public void delete(Long id) {
        System.out.println("刪除");
    }
}

//MyCglib_Test
public class MyCglib_Test {
    @Test
    public void MyCglib(){
        ProductDao productDaoImlp = new ProductDaoImlp();

        ProductDao proxy = (ProductDao)new MyCglib(productDaoImlp).createProxy();
        proxy.save(new Product());
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容