动态代理
相对于静态代理,动态代理在创建代理对象上更加的灵活,动态代理类的字节码在程序运行时,由java反射机制动态产生。它会根据需要,通过反射机制在程序运行期,动态的为目标对象创建代理对象,无需手动编写源代码。动态代理简化了编程工作,提高了软件系统的可扩展性,因为反射机制可以生成任意类型的动态代理。代理的行为可以代理多个方法,即满足生产需要的同时又达到代码通用的目的。
-
动态代理的两种实现方式:
1. JDK 动态代理(缺点:需要定义接口) 2. CGLIB动态代理
-
动态代理的特点
- 目标对象不固定
- 在应用程序执行时动态创建目标对象
- 代理对象会增强目标对象的行为
- 引入依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
- 目标类
public class User {
public String toStudy(String name){
System.out.println(name+"去学习.....");
return "签到:"+name;
}
}
- 代理类
/**
* cglib动态代理
* 继承思想
* 创建一个代理类,代理类是目标类的子类,代理类对目标类中的方法进行重写
*/
public class CglibProxy {
//目标对象
private Object targer;
public CglibProxy(Object targer) {
this.targer = targer;
}
/**
* 得到代理对象
* @return
*/
public Object getProxy(){
//通过Enhancer对象的create()方法生成一个类,用于生成代理对象
Enhancer enhancer = new Enhancer();
//设置当前类的父类(将目标类作为代理类的父类)
enhancer.setSuperclass(targer.getClass());
//定义MethodInterceptor拦截器
MethodInterceptor methodInterceptor = new MethodInterceptor() {
/**
* 代理过程
* 当代理对象调用方法时,intercept方法就会被执行
* @param o 由CGlib动态生成的代理类实例
* @param method 目标方法
* @param objects 方法所需要的参数
* @param methodProxy 代理对象对方法的引用
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("执行前。。。");
Object result = method.invoke(targer, objects);
System.out.println("执行后。。。");
return result;
}
};
//设置代理过程(调用目标对象方法、增强用户行为)
enhancer.setCallback(methodInterceptor);
//生产一个类
return enhancer.create();
}
}
- 测试
public class App {
//不用定义接口
public static void main( String[] args ) {
User user = new User();
CglibProxy cglibProxy = new CglibProxy(user);
User proxy = (User)cglibProxy.getProxy();
String name = "小明";
String s = proxy.toStudy(name);
System.out.println(s);
}
}
网友评论