一:静态代理
在使用静态代理时,需要定义接口或者父类。被代理对象(目标对象)和代理对象都需要实现同一接口或者继承父类。
使用步骤:
1:定义一个接口IStudentDao
2:被代理对象(目标对象)StudentDao实现接口
3:代理对象StudentDaoProxy也需要实现接口
4:代理对象调用被代理对象方法
具体实现:
IStudentDao
public interface IStudentDao {
void study();
}
StudentDao
public class StudentDao implements IStudentDao{
@Override
public void study() {
System.out.println("小明正在学习中...");
}
}
StudentDaoProxy
public class StudentDaoProxy implements IStudentDao {
private IStudentDao stu;//被代理对象,通过接口依赖
public StudentDaoProxy(IStudentDao stu) {
this.stu = stu;
}
@Override
public void study() {
System.out.println("被代理对象方法执行前..."); //这里可以写一些增强方法
stu.study();
System.out.println("被代理对象方法执行后...");
}
}
Client
public class Main {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
// IStudentDao stu = new StudentDao();//代理对象
IStudentDao proxyStu = new StudentDaoProxy(StudentDao.class.newInstance());//代理对象
proxyStu.study();
}
}
运行结果:

二:JDK动态代理
jdk动态代理是代理模式实现的一种方法。也是需要实现接口的。主要是通过反射来动态生成代理类。被代理对象需要实现接口,代理对象不需要实现接口;
生成代理对象的JDK API:
/**
*loader:类加载器
*interfaces:被代理类实现的接口
*h:重写invocationHandler中的invoke,
*return:返回一个代理对象
*/
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
IStudentDao:
public interface IStudentDao {
void study();
}
StudentDao
public class StudentDao implements IStudentDao {
@Override
public void study() {
System.out.println("小明正在学习......");
}
}
ProxyFactory:
//实现InvocationHandler接口,重写invoke方法
public class ProxyFactory implements InvocationHandler{
private Object target;//被代理的对象;
public ProxyFactory(Object target) {
this.target = target;
}
//返回一个代理对象
public Object getProxyInstance()
{
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this
);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk代理开始");
Object invoke = method.invoke(target, args);
System.out.println("jdk代理结束");
return invoke;
}
}
测试:
public class Main {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
IStudentDao stu = new StudentDao();
IStudentDao instance = (IStudentDao)new ProxyFactory(stu).getProxyInstance();
instance.study();
}
}
结果:

三:cglib实现动态代理
无论是静态代理或者是jdk动态代理都需要实现一个接口。有时候我们只有一个对象,没有实现任何接口的。这时候可以使用目标对象子类来实现动态代理。cglib代理
通过在内存中构建子类从而实现对目标对象方法的扩建。
先导入依赖:
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.8</version>
</dependency>
StudentDao
public class StudentDao {
public void study()
{
System.out.println("小明正在学习......");
}
}
ProxyFactory
public class ProxyFactory implements MethodInterceptor {
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
public Object getProxyInstance()
{
//1.创建一个工具类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(target.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类,即代理对象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib代理开始");
Object res = method.invoke(target, objects);
System.out.println("cglib代理结束");
return res;
}
}
Main
public class Main {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
ProxyFactory proxyFactory = new ProxyFactory(StudentDao.class.newInstance());
StudentDao instance = (StudentDao)proxyFactory.getProxyInstance();
instance.study();
}
}

四:总结
1:静态代理和jdk动态代理都需要实现接口,而cglib不用实现接口。
2:代理模式可以在不修改被代理对象(目标对象)的前提下,对目标对象进行扩展。
3:静态代理每次修改接口都需要维护目标对象和被代理对象。
4:你所热爱的,就是你的生活。