Spring学习之JDK代理和Gclib代理

Spring学习之JDK代理和Gclib代理

在Spring框架中,使用JDK动态代理和CGLIB代理是为了支持面向切面编程(AOP)。Spring AOP默认会根据目标bean是否实现接口来选择使用JDK动态代理还是CGLIB代理。这个选择过程是自动的,但您也可以通过配置来显式指定使用哪一种代理方式。

JDK动态代理

JDK动态代理主要用于代理实现了接口的对象。在Spring中,默认情况下,如果目标bean实现了至少一个接口,Spring AOP会使用JDK动态代理。

如何使用
  1. 定义接口:创建一个或多个接口,定义需要代理的方法。
  2. 实现接口:创建类实现这些接口。
  3. 启用AOP:在Spring配置中启用AOP。
package com.phl.aop.pojo;

public interface IUser {

    void pay();
}


package com.phl.aop.pojo;

import org.springframework.stereotype.Component;

@Component
public class User implements IUser{

    /**
     * 支付功能
     */
    public void pay(){
        System.out.println("用户进行了支付");
    }
}
package com.phl.aop.pojo;

public interface IStudent {

    String study();
}



package com.phl.aop.pojo;

import org.springframework.stereotype.Component;

@Component
public class Student implements IStudent{

    @Override
    public String study() {
        System.out.println("同学进行了Spring的课程学习");
        return "学到了Spring的知识点";
    }

    public void say_hello(){
        System.out.println("SayHello");
    }

}

CGLIB代理

如果目标bean没有实现任何接口,Spring AOP会自动使用CGLIB来创建代理。CGLIB代理适用于代理普通的Java类,因为它是通过子类化的方式来实现代理的。

如何使用
  1. 创建类:创建一个普通的Java类,不需要实现任何接口。
  2. 启用AOP:在Spring配置中启用AOP。
package com.phl.aop.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Employee {

    @Value("1001")
    private int empId;
    @Value("Tom")
    private String empName;

    public void details(){
        System.out.println("员工信息,工号:"+empId+",姓名:"+empName);
    }
}

测试

import com.phl.aop.pojo.*;
import com.phl.aop.proxy.CglibProxy;
import com.phl.aop.proxy.JdkProxy;
import com.phl.aop.proxy.UserProxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring.xml")
public class SpringTest {
    //静态代理类
    @Resource
    private UserProxy userProxy;

    //JDK动态代理类
    @Resource
    private JdkProxy jdkProxy;

    @Resource
    private IUser user;

    @Resource
    private IStudent student;
    @Resource
    private CglibProxy cglibProxy;

    @Resource
    private Employee employee;
    //@Test
    public void test1(){
        userProxy.pay();
    }

    //@Test
    public void test2(){
//        //生成代理类,代理类实现了代理目标的接口
//        IUser u = (IUser) jdkProxy.createProxy(user);
//        //获取类的类名
//        //System.out.println(u.getClass().getName());
//        u.pay();

        //生成Student类的代理类
        IStudent stu = (IStudent) jdkProxy.createProxy(student);
        System.out.println(stu.getClass().getName());
        String studyResult = stu.study();
        System.out.println("学习成果:"+studyResult);
    }

    //@Test
    public void test3(){
        Student stu = (Student) cglibProxy.createProxy(student);
        stu.study();
        //stu.say_hello();
    }

    @Test
    public void test4(){
        user.pay();
        student.study();
        employee.details();
    }
}

在上面代码中,自动装配时,对象user和student的类型都必须是接口类型,使用的是JDK代理,因为Student和User实现了IStudent和IUser接口,spring会默认生成JDK代理

而Employee的对象并没有实现接口,所以默认是Cglib代理

你可能感兴趣的:(Java,java,spring,学习)