動(dòng)態(tài)代理AOP

千峰牛逼
動(dòng)態(tài)代理

jdk代理方式

    新建接口

public interface IUserService<T> {

/**
 * 獲取所有的用戶對(duì)象列表
 * @return
 */
List<T> getAllUser();

/**
 * 保存用戶
 * @param user
 * @return
 */
boolean saveUser(T user);

/**
 * 根據(jù)用戶uid刪除該uid對(duì)應(yīng)的用戶信息
 * @param uid
 * @return
 */
boolean deleteUser(int uid);

/**
 * 更新指定用戶信息
 * @param obj
 * @return
 */
boolean updateUser(T obj);

}

實(shí)現(xiàn)接口

實(shí)現(xiàn)代理方法

public class UserFactory {

public static IUserService getUserService(){

    IUserService us = new UserservcieImpl();//被代理的對(duì)象

    MyAspect ma = new MyAspect();//需要添加的代理

    /**
     * @param UserFactory.class.getClassLoader() 類加載器,用來(lái)加載代理類
     * @param us.getClass().getInterfaces() 被代理的接口
     * @param new InvocationHandler() 內(nèi)部類 重寫(xiě)invoke方法
     */
    IUserService ius = (IUserService) Proxy.newProxyInstance(UserFactory.class.getClassLoader()
            , us.getClass().getInterfaces(), new InvocationHandler() {

        /**
         * 代理對(duì)象調(diào)用的回掉方法
         * @param proxy 代理對(duì)象
         * @param method 被代理的方法
         * @param args 被代理方法的參數(shù)列表對(duì)象
         * @return 每個(gè)方法的最終返回值
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            ma.before();

            Object obj = method.invoke(us, args);//原方法

            ma.after();

            return obj;
        }
    });

    return ius;
}

}
cglib代理方式

與jdk代理相似,代理方法有所不同

基本原理
    使用Enhancer生成原有類的子類,設(shè)置好回掉(callback),那么原有類的所有方法都會(huì)被攔截然后調(diào)用實(shí)現(xiàn)了MethodInterceptor的intercept()方法.

提示:如果原方法是final類型的,則MethodInterceptor無(wú)法攔截

代理方法

public class UserFactory {

/**
 * 使用Spring中的一個(gè)增強(qiáng)類來(lái)實(shí)現(xiàn)aop方式
 *      1.  創(chuàng)建Enhancer對(duì)象
 *      2.  設(shè)置增強(qiáng)類Enhancer的superClass
 *      3.  設(shè)置Enhancer對(duì)象的回調(diào)
 *      4.  通過(guò)eh對(duì)象的create()方法來(lái)得到指定的對(duì)象
 * @return
 */
public static IUserService getUserService(){
    //  1.  創(chuàng)建Enhancer對(duì)象
    Enhancer eh = new Enhancer();
    //  2.  設(shè)置增強(qiáng)類Enhancer的superClass
    eh.setSuperclass(IUserService.class);

    IUserService<Object> us = new UserServiceImpl<>();//需要代理的對(duì)象
    MyAspect ma = new MyAspect();//
    //  3.  設(shè)置Enhancer對(duì)象的回調(diào)
    eh.setCallback(new MethodInterceptor() {
        
        /**
        * Object o:被代理的對(duì)象
        * Method method:被攔截的方法
        * Object[] objects:被攔截的方法的參數(shù)們
        * MethodProxy methodProxy:MethodProxy類型的被攔截方法
        **/
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

            ma.before();

            Object obj = method.invoke(us, objects);

            ma.after();

            return obj;
        }
    });

    //  4.  通過(guò)eh對(duì)象的create()方法來(lái)得到指定的對(duì)象
    IUserService<Object> ius = (IUserService<Object>) eh.create();

    return ius;
}

}
jdk代理方式與cglib代理方式的區(qū)別

JDK代理只能對(duì)實(shí)現(xiàn)了接口的類生成代理,而CGLIB是通過(guò)繼承的方式實(shí)現(xiàn)代理也可以為實(shí)現(xiàn)了接口的類強(qiáng)制使用
JDK代理在使用次數(shù)較少時(shí)效率高于CGLIB代理,當(dāng)大量使用時(shí)CGLIB代理更勝一籌.但隨著jdk版本的升級(jí),JDK代理效率不斷提升,到j(luò)dk8時(shí)高于CGLIB代理

spring框架中的動(dòng)態(tài)代理方式

創(chuàng)建被代理類接口并實(shí)現(xiàn)接口
創(chuàng)建代理類,并實(shí)現(xiàn)MethodInterceptor接口

    重寫(xiě)invoke方法

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {

    before();

    //  業(yè)務(wù)處理方法的調(diào)用
    Object obj = invocation.proceed();

    after();

    return obj;
}

配置beans.xml

分別配置被代理類bean(id="us")和代理類bean(id="my")

配置代理工廠
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="interfaces" value="com.qfedu.aop03.IUserService" />
    <property name="target" ref="us" />
    <property name="interceptorNames" value="my" />
    <property name="optimize" value="true" />
</bean>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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