静态代理

实现方法:和目标对象继承同一个接口。
因为本质是一个class对象,所以叫静态代理。
image.png

动态代理:Proxy

必须传入接口实现的类。

  1. public class ProxyJdk {
  2. public <T> T create(T t) {
  3. Class<?> aClass = t.getClass();
  4. Object o = Proxy.newProxyInstance(aClass.getClassLoader(),
  5. aClass.getInterfaces(), (proxy, method, args) -> {
  6. //如果要对不同方法代理不一样,可以通过method.getName()来判断
  7. System.out.println("jdk代理开始");
  8. Object invoke = method.invoke(t, args);
  9. System.out.println("jdk代理结束");
  10. return invoke;
  11. });
  12. return (T) o;
  13. }
  14. public static void main(String[] args) {
  15. // 必须用接口,否则会转换失败
  16. UserTestService userTestService = new UserTestServiceImpl();
  17. UserTestService user1 = new ProxyJdk().create(userTestService);
  18. System.out.println(user1.power(123));
  19. }
  20. }

cglib代理

可以直接传入普通对象。
CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。

  1. import org.springframework.cglib.proxy.Enhancer;
  2. import org.springframework.cglib.proxy.MethodInterceptor;
  3. import org.springframework.cglib.proxy.MethodProxy;
  4. import java.lang.reflect.Method;
  5. public class ProxyCglib {
  6. public <T> T create(T t) {
  7. Object o = Enhancer.create(t.getClass(), new MethodInterceptor() {
  8. @Override
  9. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  10. System.out.println("=====");
  11. Object invoke = method.invoke(t, objects);
  12. System.out.println("!!!!!");
  13. return invoke;
  14. }
  15. });
  16. return (T) o;
  17. }
  18. public static void main(String[] args) {
  19. User user = new User();
  20. User user1 = new ProxyCglib().create(user);
  21. user1.setName("hello");
  22. System.out.println(user1);
  23. }
  24. }