动态代理AOP

千峰牛逼
动态代理

jdk代理方式

    新建接口

public interface IUserService<T> {

/**
 * 获取所有的用户对象列表
 * @return
 */
List<T> getAllUser();

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

/**
 * 根据用户uid删除该uid对应的用户信息
 * @param uid
 * @return
 */
boolean deleteUser(int uid);

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

}

实现接口

实现代理方法

public class UserFactory {

public static IUserService getUserService(){

    IUserService us = new UserservcieImpl();//被代理的对象

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

    /**
     * @param UserFactory.class.getClassLoader() 类加载器,用来加载代理类
     * @param us.getClass().getInterfaces() 被代理的接口
     * @param new InvocationHandler() 内部类 重写invoke方法
     */
    IUserService ius = (IUserService) Proxy.newProxyInstance(UserFactory.class.getClassLoader()
            , us.getClass().getInterfaces(), new InvocationHandler() {

        /**
         * 代理对象调用的回掉方法
         * @param proxy 代理对象
         * @param method 被代理的方法
         * @param args 被代理方法的参数列表对象
         * @return 每个方法的最终返回值
         * @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生成原有类的子类,设置好回掉(callback),那么原有类的所有方法都会被拦截然后调用实现了MethodInterceptor的intercept()方法.

提示:如果原方法是final类型的,则MethodInterceptor无法拦截

代理方法

public class UserFactory {

/**
 * 使用Spring中的一个增强类来实现aop方式
 *      1.  创建Enhancer对象
 *      2.  设置增强类Enhancer的superClass
 *      3.  设置Enhancer对象的回调
 *      4.  通过eh对象的create()方法来得到指定的对象
 * @return
 */
public static IUserService getUserService(){
    //  1.  创建Enhancer对象
    Enhancer eh = new Enhancer();
    //  2.  设置增强类Enhancer的superClass
    eh.setSuperclass(IUserService.class);

    IUserService<Object> us = new UserServiceImpl<>();//需要代理的对象
    MyAspect ma = new MyAspect();//
    //  3.  设置Enhancer对象的回调
    eh.setCallback(new MethodInterceptor() {
        
        /**
        * Object o:被代理的对象
        * Method method:被拦截的方法
        * Object[] objects:被拦截的方法的参数们
        * 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.  通过eh对象的create()方法来得到指定的对象
    IUserService<Object> ius = (IUserService<Object>) eh.create();

    return ius;
}

}
jdk代理方式与cglib代理方式的区别

JDK代理只能对实现了接口的类生成代理,而CGLIB是通过继承的方式实现代理也可以为实现了接口的类强制使用
JDK代理在使用次数较少时效率高于CGLIB代理,当大量使用时CGLIB代理更胜一筹.但随着jdk版本的升级,JDK代理效率不断提升,到jdk8时高于CGLIB代理

spring框架中的动态代理方式

创建被代理类接口并实现接口
创建代理类,并实现MethodInterceptor接口

    重写invoke方法

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

    before();

    //  业务处理方法的调用
    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>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容