介绍
JDK的动态代理只能代理实现了接口的类,而不能实现接口的类就不可以使用JDK动态代理,cglib是针对类来实现代理的,它的原理是针对指定目标生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,因此不能对final修饰的类进行代理。
jdk动态代理实例
目录:
代码:
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class jdkProxy {
private Object target;
public jdkProxy(Object target)
{
this.target = target;
//通过带参构造,传递目标对象
}
public Object getProxy(){
ClassLoader classLoader = this.getClass().getClassLoader();
//得到类加载器
Class [] interfaces = target.getClass().getInterfaces();//注意是target.getclass
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//只要代理对象中的方法被调用了invoke就会执行一次
//在invoke中执行目标对象的方法
//method是目标对象的方法
method.invoke(target,args);//target是要代理的对象,args是目标对象方法中的参数
System.out.println("begin invoke");
return null;
}
};
//得到代理对象(代理实例)
Object proxy = Proxy.newProxyInstance(classLoader,interfaces,invocationHandler);
return proxy;//返回代理
}
}
import bean.Marry;
import bean.Rent;
import bean.User;
public class ProxyTest {
public static void main(String[] args) {
Rent rentTarget = new User();//目标对象
jdkProxy jdkproxy = new jdkProxy(rentTarget);//目标对象传给带参构造器
Rent rent1 = (Rent) jdkproxy.getProxy();
rent1.RentHouse();
//=====================================代理2===============================
Marry marryTarget = new User();
jdkProxy jdkproxy2 = new jdkProxy(marryTarget);
Marry marry = (Marry) jdkproxy2.getProxy();
marry.getMarry();
}
}
接口:
public interface Marry {
void getMarry();
}
public interface Rent {
public void RentHouse();
}
实现类:
public class User implements Rent,Marry {
@Override
public void RentHouse() {
System.out.println("rent house and jdkproxy 实现接口的实例");
}
@Override
public void getMarry() {
System.out.println("实例的方法 getmarry 实现marry接口");
}
}
测试的函数:
public class ProxyTest {
public static void main(String[] args) {
Rent rentTarget = new User();//目标对象
jdkProxy jdkproxy = new jdkProxy(rentTarget);//目标对象传给带参构造器
Rent rent1 = (Rent) jdkproxy.getProxy();
rent1.RentHouse();
//=====================================代理2===============================
Marry marryTarget = new User();
jdkProxy jdkproxy2 = new jdkProxy(marryTarget);
Marry marry = (Marry) jdkproxy2.getProxy();
marry.getMarry();
}
}
输出:
cglib动态代理实例
cglib的关键是:继承(目标对象作为父类)
一定要注意导入cglib的jar:
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.MethodInterceptor;
import java.lang.reflect.Method;
public class Cglibproxy {
private Object target;
public Cglibproxy(Object target)
{
this.target = target;
}
//获取代理对象
public Object getproxy()
{
//通过enhancer对象的create()方法可以生成一个类,用于生产代理对象
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());//设置目标对象为父类
MethodInterceptor methodInterceptor = new MethodInterceptor() {
@Override
public Object intercept(Object ob, Method method, Object[]obj, MethodProxy methodproxy) throws Throwable
{
System.out.println("方法执行前");
Object object = methodproxy.invoke(target,obj);//调用目标对象的方法
//进行行为增强 可以加入非业务之外的其他功能
System.out.println("方法执行后");
return object;
}
};
enhancer.setCallback(methodInterceptor);//设置拦截器,回调对象为本身对象
return enhancer.create();//返回生成的一个代理对象
}
}
public class User2 {
public void cglibtest()
{
System.out.println("测试cglib");
}
}
public class CglibTest {
public static void main(String[] args) {
User2 user2 = new User2();
Cglibproxy cglibproxy = new Cglibproxy(user2);
User2 proxy = (User2)cglibproxy.getproxy();
proxy.cglibtest();
}
}
输出:
在这种代理下即使没有实现接口也没关系。