一、java原生代理
1、代理概念介绍
为某个对象提供一个代理,以控制对这个对象的访问。
代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理
对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行
完请求后的后续处理。
2、代理分类
java代理分为两类,静态代理和动态代理。
静态代理通过代码的编写,生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。
3、动态代理示例
使用java.lang.reflect.Proxy进行创建
3.1 接口部分
使用Proxy创建代理,必须预先定义接口
package wang.conge.javasedemo.core.proxy;
public interface HelloService {
public String sayHello(String name);
}
3.2 业务实现部分
package wang.conge.javasedemo.core.proxy;
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "hello:" + name;
}
}
3.3 代理业务部分
package wang.conge.javasedemo.core.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class HelloInvocationHandler implements InvocationHandler{
private Object delegate;
public HelloInvocationHandler(Object delegate){
this.delegate = delegate;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke");
return method.invoke(this.delegate, args);
}
}
3.4 测试代码
package wang.conge.javasedemo.core.proxy;
import java.lang.reflect.Proxy;
public class JavaProxyTest {
public static void main(String[] args) {
HelloInvocationHandler invocationHandler = new HelloInvocationHandler(new HelloServiceImpl());
HelloService helloService = (HelloService) Proxy.newProxyInstance(HelloService.class.getClassLoader(),
new Class[] { HelloService.class }, invocationHandler);
System.out.println(helloService.sayHello("conge"));
}
}
运行结果
invokehello:conge
3.5 Proxy代理总结
用法总结:
主要使用java.lang.reflect.Proxy 进行创建代理类
主要方法:public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h);
第一个参数是ClassLoader,也即是加载所要代理类的相应的ClassLoader
第二个参数是interfaces,即是所要代理类的接口
第三个参数是代理业务部分,需要实现InvocationHandler接口
优缺点总结:
优点:
1、可以替代java静态代理,集中式处理
缺点:
1、所代理的类,必须预先定义接口,不能直接没有定义接口的类
2、所代理的接口也必须是public类型,如果是package ,必须在访问包的顶层目录
二、Cglib代理
因为Proxy不能代理没有定义接口的类,缺陷比较大。但还有另外一个方案可以解决这个问题。cglib。
1.cglib介绍
cglib简述
Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理:
使用CGLIB需要导入以下两个jar文件:
$1: asm.jar – CGLIB的底层实现
$2: cglib.jar – CGLIB的核心jar包。
CGLIB的核心类:
net.sf.cglib.proxy.Enhancer – 主要的增强类
net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现
net.sf.cglib.proxy.MethodProxy – JDK的Java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用,如使用:
Object o = methodProxy.invokeSuper(proxy, args);//虽然第一个参数是被代理对象,也不会出现死循环的问题。
2.使用cglib进行代理
2.1 所依赖cglib
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.2</version></dependency>
2.2 业务服务
还是使用java原生代理的HelloServiceImpl , see 原生代理3.2
2.3 代理业务部分
package wang.conge.javasedemo.core.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class HelloCglibHandler implements MethodInterceptor {
private Object delegate;
public HelloCglibHandler(Object delegate){
this.delegate = delegate;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("intercept");
return method.invoke(delegate, args);
}
}
2.4 测试代码
package wang.conge.javasedemo.core.cglib;
import net.sf.cglib.proxy.Enhancer;
import wang.conge.javasedemo.core.proxy.HelloServiceImpl;
public class EnhancerTest {
public static void main(String[] args) {
HelloCglibHandler cglibHandler = new HelloCglibHandler(new HelloServiceImpl());
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(HelloServiceImpl.class);
enhancer.setCallback(cglibHandler);
HelloServiceImpl helloService = (HelloServiceImpl) enhancer.create();
System.out.println(helloService.sayHello("conge"));
}
}
运行结果:
intercepthello:conge
2.5 cglib代理总结
主要使用Enhancer进行创建代理类,可以直接对类进行代理,运行速度也比原生代理要快。
相关推荐
spring之AOP(动态代理),包括jdk动态代理和CGLib动态代理
静态代理--不适合企业开发,适合初学者理解代理。 jdk动态代理--适合企业级开发,但是它要求必须面向接口编程,假如目标类没有实现接口...spring 的AOP功能中 会根据目标类是否实现了接口来判断使用 jdk Proxy还是cglib
SpringAOP动态代理 Spring AOP 使用的动态代理主要有两种方式:JDK 动态代理和 CGLIB 代理。 JDK 动态代理:用于代理实现了接口的类。Spring 会使用 java.lang.reflect.Proxy 类来创建代理对象。 CGLIB 代理:用于...
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换 如何强制使用CGLIB实现AOP? * 添加CGLIB库,SPRING_HOME/cglib/*.jar * 在spring配置文件中加入<aop:aspectj-...
package com.gc.aop下为:aop方式ProxyFactoryBean代理...package com.gc.javaproxy下为:java代理机制实现 package com.gc.proxy下为:自定义代理模式(面向接口编程) package com.gc.normal下为:通用日志处理方式
- Spring AOP 说在前面:今天我们来聊一聊 Java 中的代理,先来聊聊故事背景: 小明想购买法国某个牌子的香水送给女朋友,但是在国内没有货源售卖,亲自去法国又大费周章了,而小红现在正在法国玩耍,她和小明是...
org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces 从异常信息可以看出是cglib的问题...
使用JDK中的Proxy技术实现AOP功能与使用CGLIB实现AOP功能
本文档先讲解了JDK的反射机制,然后是Proxy的动态代理、CGLIB的动态代理,因为这些是Spring AOP的底层技术,清楚了它们,你就更能够理解Spring AOP是如何工作的。在文档的最后简要写了Spring AOP的使用,因为这不是...
Spring初探 准备工作 构建Spring基础代码 Spring 基础语义 Dependency Injection 依赖注入的几种实现类型 ... Dynamic Proxy 与Spring AOP CGLib 与 Spring AOP AOP 应用 DAO Support Remoting
Java 代理 代理模式 静态代理与动态代理 常见的动态代理实现 JDK Proxy CGLIB JDK Proxy 和 CGLIB 的对比 动态代理的实际应用 Spring AOP
spring AOP中的cglib代理所依赖的jar包cglib.jar源码 net.sf.cglib.proxy
* * * * JDK动态代理 JDK动态代理 JDK动态代理是通过java.lang.reflect.Proxy 类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象。对于使用业务接口的类,Spring默认会使用JDK动态代理来实现...
Spring Registrar和Spring Import Selector三种机制的AOP框架,具有很高的通用性,健壮性,可选和易用性请联系我微信,钉钉,公众号和文档简介Spring自动代理机制它统一的封装接口(Spring)代理和类代理(CGLIB),...
修改默认代理方法:<aop:aspectj-autoproxy proxy-target-class="true"/> 增强种类 前置通知 后置通知 异常通知 最终通知 环绕通知 注意:使用注解的方式,最终通知和后置通知顺序换了,建议使用环绕通知...
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................
CGlib的Proxy实现AOP的示例、JDK的Proxy实现AOP的示例、通过spring注解方式实现AOP
《Java 基础核心总结》 Java 概述 什么是 Java2 Java 的特点Java ...JDK Proxy 和 CGLIB 的对比动态代理的实际应用 Spring AOP 变量 变量汇总实例变量 实例变量的特点全局变量 静态变量 静态变量的特点类变量 局部变量
使用CGLIB实现AOP功能与AOP概念解释 17.使用Spring的注解方式实现AOP入门 18.使用Spring的注解方式实现AOP的细节 19.使用Spring配置文件实现AOP 20.aspectj的切入点语法定义细节 21.搭建和配置Spring与jdbc整合...