Aop-静态代理-jdk动态代理-CGLIB动态代理(四)

本文详细介绍了面向切面编程(AOP)的概念及其优势,并通过静态代理、JDK动态代理和CGLIB动态代理三种方式深入探讨了代理模式的具体实现。文章还分析了每种代理模式的特点及应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * AOP:面向切面编程。
 * 1.对业务逻辑的各个部分进行隔离
 * 2.耦合度降低
 * 3.提高程序的可重用性,
 * 4.同时提高了开发的效率
 * 主要的功能: 日志记录,性能统计,安全控制,事务处理,异常处理
 * 功能: 让关注点代码与业务代码分离!(关注点,重复代码就叫做关注点)(关注点形成的类,就叫切面(类)!)
 * 体现:代理模式
 */

其实所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用。

 定义:为其他对象提供一种代理,以控制对这个对象的访问。

适用场景:保护目标对象、增强目标对象。

优点:将代理对象与真实被调用对象分离,一定程度上降低了系统的耦合度,扩展性好。保护目标对象,增强目标对象。

缺点:会造成系统设计中的类的数目增加,请求速度变慢,增加系统复杂度。

静态代理类只能为特定的接口(Service)服务。如想要为多个接口服务则需要建立很多个代理类。

 动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。而且动态代理的应用使我们的类职责更加单一,复用性更强

  1. 静态代理

    /**
     * 方法接口
     */
    public interface IUserDao {
        void save();
    }


    /**
     * 接口实现
     */
    public class UserDao implements IUserDao {
        @Override
        public void save() {
            System.out.println("存储数据");
        }
    }

    
    /**
     * 代理类
     */
    public static class UserDaoProxy implements IUserDao {
        private UserDao userDao;

        public UserDaoProxy(UserDao userDao) {
            this.userDao = userDao;
        }

        @Override
        public void save() {
            System.out.println("检测数据类型是否符合标准");
            userDao.save();
            System.out.println("打印日志");
        }
    }

        
    /**
     * 具体方法调用
     */
    public static void main(String[] args) {
        //静态代理
        new UserDaoProxy(new UserDao()).save();
    }

    

2、jdk动态代理

/**
 * Created on 2019/4/5.
 * jdk动态代理
 * 实现类,所以必须使用接口
 * 缺点:jdk动态代理,必须是面向接口,目标业务类必须实现接口
 *
 * @author Grak
 * @since 1.0
 */
public class JDKProxy implements InvocationHandler {

    // 这其实业务实现类对象,用来调用具体的业务方法
    private Object target;

    public JDKProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("调用开始处理");
        result = method.invoke(target, args);
        System.out.println("调用结束处理");
        return result;
    }

    public static void main(String[] args) {
        IUserDao userDao = new UserDao();// 被代理对象
        JDKProxy invocationHandlerImpl = new JDKProxy(userDao);//代理方法
        ClassLoader loader = userDao.getClass().getClassLoader();//类信息
        Class<?>[] interfaces = userDao.getClass().getInterfaces();//接口
        // 主要装载器、绑定类,接口,代理方法
        BaseSaticProxy.IUserDao newProxyInstance = (BaseSaticProxy.IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);
        newProxyInstance.save();
    }
}

 

3、CGLIB动态代理

/**
 * Created on 2019/4/5.
 * CGLIB动态代理
 * 不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码
 *
 * @author Grak
 * @since 1.0
 */
public class CGLIBProxy implements MethodInterceptor {

    private Object targetObject;

    public Object getInstance(Object target) {
        // 设置需要创建子类的类
        this.targetObject = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开启事物");
        Object result = methodProxy.invoke(targetObject, objects);
        System.out.println("关闭事物");
        // 返回代理对象
        return result;
    }

    public static void main(String[] args) {
        CGLIBProxy cglibProxy = new CGLIBProxy();
        BaseSaticProxy.IUserDao userDao = (BaseSaticProxy.IUserDao) cglibProxy.getInstance(new BaseSaticProxy.UserDao());
        userDao.save();
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值