cglip动态代理和jdk动态代理区别是什么,优缺点是什么

CGLIB动态代理和JDK动态代理是两种不同的代理实现方式,它们有一些区别和各自的优缺点。
 区别:
1. 实现方式:CGLIB动态代理通过继承被代理类来创建代理类,而JDK动态代理通过实现被代理接口来创建代理类。
2. 支持的代理对象类型:CGLIB动态代理可以代理任意类,而JDK动态代理只能代理实现了接口的类。
3. 性能:CGLIB动态代理在创建代理类时需要使用ASM字节码操作库来修改字节码,相比之下,JDK动态代理的创建过程更加简单,性能略好一些。
 优点和缺点:
CGLIB动态代理的优点:
1. 可以代理任意类,不需要被代理类实现接口。
2. 在方法调用前后可以添加额外的逻辑,实现更加灵活的方法拦截和增强。
 CGLIB动态代理的缺点:
1. 由于是通过继承被代理类来创建代理类,因此无法代理被标记为final的类和方法。
2. 由于使用了字节码操作,创建代理类的过程相对较慢,性能较差。
 JDK动态代理的优点:
1. 创建代理类的过程相对简单,性能较好。
2. JDK动态代理是Java自带的标准库,无需额外依赖。
 JDK动态代理的缺点:
1. 只能代理实现了接口的类,无法代理未实现接口的类。
2. 在方法调用前后添加额外的逻辑的能力相对较弱。
 综上所述,CGLIB动态代理适用于代理任意类,对性能要求不是很高的场景;JDK动态代理适用于代理实现了接口的类,对性能要求较高的场景。

CGLIB(Code Generation Library)是一个基于ASM(一个Java字节码操作和分析框架)的代码生成库,它可以在运行时动态生成代理类。相比于JDK动态代理,CGLIB动态代理不要求被代理类实现接口,可以代理任意类。
 CGLIB动态代理的原理是通过继承被代理类来创建一个子类作为代理类。在子类中,重写被代理类的方法,并在方法调用前后添加额外的逻辑。CGLIB通过修改字节码的方式实现了这一过程。
 下面是使用CGLIB动态代理的代码实现示例:
 1. 添加CGLIB依赖:
xml

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>


2. 创建被代理类:

public class UserService {
    public void addUser() {
        System.out.println("添加用户");
    }
}


3. 创建代理类:

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.Enhancer;
 public class UserServiceProxy implements MethodInterceptor {
    private Object target; // 被代理的对象
     public Object getProxyInstance(Object target) {
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
     @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("方法调用前");
        Object result = method.invoke(target, args);
        System.out.println("方法调用后");
        return result;
    }
}


4. 测试代码:

public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService();
        UserServiceProxy proxy = new UserServiceProxy();
        UserService userServiceProxy = (UserService) proxy.getProxyInstance(userService);
        userServiceProxy.addUser();
    }
}


运行以上代码,输出结果为:

方法调用前
添加用户
方法调用后


通过CGLIB动态代理,我们成功地对UserService类进行了方法拦截和增强。在代理类的intercept方法中,我们可以在方法调用前后添加额外的逻辑,实现了AOP的横切关注点。

JDK(Java Development Kit)动态代理是Java提供的一种动态代理技术,它通过反射机制在运行时动态生成代理类。JDK动态代理要求被代理类实现接口。
 JDK动态代理的原理是通过Proxy类和InvocationHandler接口实现的。Proxy类用于创建代理对象,InvocationHandler接口用于定义代理对象的方法调用处理逻辑。
 下面是使用JDK动态代理的代码实现示例:
 1. 创建被代理接口:

public interface UserService {
    void addUser();
}


2. 创建被代理类:

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("添加用户");
    }
}


3. 创建代理类:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 public class UserServiceProxy implements InvocationHandler {
    private Object target; // 被代理的对象
     public Object getProxyInstance(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
     @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法调用前");
        Object result = method.invoke(target, args);
        System.out.println("方法调用后");
        return result;
    }
}
4. 测试代码:
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserServiceProxy proxy = new UserServiceProxy();
        UserService userServiceProxy = (UserService) proxy.getProxyInstance(userService);
        userServiceProxy.addUser();
    }
}


运行以上代码,输出结果为:

方法调用前
添加用户
方法调用后


通过JDK动态代理,我们成功地对UserServiceImpl类进行了方法拦截和增强。在代理类的invoke方法中,我们可以在方法调用前后添加额外的逻辑,实现了AOP的横切关注点。

使用Spring AOP实现CGLIB动态代理的代码如下:
 1. 首先,需要添加CGLIB的依赖包。在Maven项目中,可以在pom.xml文件中添加以下依赖:
xml

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>


2. 创建被代理类:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>


3. 创建切面类:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>


4. 配置Spring AOP:
xml

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>


5. 测试代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.addUser();
    }
}


运行以上代码,输出结果为:

添加用户
方法调用后


通过Spring AOP结合CGLIB动态代理,我们成功地对UserService类的addUser方法进行了方法拦截和增强。在切面类的logAfter方法中,我们可以在方法调用后添加额外的逻辑,实现了AOP的横切关注点。

使用Spring AOP实现JDK动态代理的代码如下:
1. 创建被代理接口:

public interface UserService {
    void addUser();
}


2. 创建被代理类实现该接口:

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("添加用户");
    }
}


3. 创建切面类:

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("添加用户");
    }
}


4. 配置Spring AOP:
xml

<bean id="userService" class="com.example.UserServiceImpl"/>
<bean id="loggingAspect" class="com.example.LoggingAspect"/>
<aop:config>
    <aop:aspect ref="loggingAspect">
        <aop:pointcut id="userServicePointcut" expression="execution(* com.example.UserService.addUser(..))"/>
        <aop:after pointcut-ref="userServicePointcut" method="logAfter"/>
    </aop:aspect>
</aop:config>


5. 测试代码:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.addUser();
    }
}


运行以上代码,输出结果为:

添加用户
方法调用后


通过Spring AOP结合JDK动态代理,我们成功地对UserService接口的addUser方法进行了方法拦截和增强。在切面类的logAfter方法中,我们可以在方法调用后添加额外的逻辑,实现了AOP的横切关注点。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值