静态代理
由程序创建或者特定工具生成的源代码,在程序运行前,代理类的.class文件已经生成
通过将目标类与代理类实现同一个接口,让代理类持有真实类对象
在代理类方法中调用真实类方法,在调用真实类方法的前后添加我们所需要的功能扩展代码来达到增强的目的
public interface ClothFactory {
/**
* 生产衣服
*/
void produceCloth();
}
// 被代理类
public class NikeClothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("Nike开始生产衣服");
}
}
public class ClothProxyFactory implements ClothFactory{
// 创建代理类对象
private ClothFactory clothFactory;
public ClothProxyFactory(ClothFactory clothFactory){
this.clothFactory = clothFactory;
}
/**
* 对被代理类的方法进行拦截处理
*/
@Override
public void produceCloth() {
System.out.println("服饰工厂开始准备");
// 被代理类方法执行
clothFactory.produceCloth();
System.out.println("服饰工厂准备结束");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
// 被代理类
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ClothProxyFactory clothProxyFactory = new ClothProxyFactory(nikeClothFactory);
clothProxyFactory.produceCloth();
}
}
动态代理
- JDK动态代理,要求目标对象实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候就可以用CGLib动态代理
- JDK动态代理是自带的,CGLib需要引入第三方包
- CGLib动态代理,是在内存中构建一个子类对象从而实现对目标对象功能的扩展
- CGLib动态代理基于继承来实现代理,所以无法对final类、private方法和static方法实现代理
JDK动态代理
public interface Human {
void breath();
void eat(String food);
}
public class Student implements Human{
@Override
public void breath() {
System.out.println("呼吸最新鲜的空气");
}
@Override
public void eat(String food) {
System.out.println("学生应该吃:"+food);
}
}
public class JDKProxy implements InvocationHandler {
// 创建被代理类对象
private Object targetObj;
// 返回被代理对象
public Object newInstance(Object targetObj){
this.targetObj = targetObj;
return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("动态代理开始----------调用方法"+method.getName());
Object result = method.invoke(targetObj,args);
System.out.println("动态代理结束----------调用方法"+method.getName());
return result;
}
}
public class JDKProxyTest {
public static void main(String[] args) {
// 创建被代理类
Student student = new Student();
// JDK动态代理类
JDKProxy jdkProxy = new JDKProxy();
Human human = (Human) jdkProxy.newInstance(student);
human.breath();
human.eat("有营养的食物");
}
}
CGLib动态代理
public interface Human {
void breath();
void eat(String food);
}
public class Student implements Human{
@Override
public void breath() {
System.out.println("呼吸最新鲜的空气");
}
@Override
public void eat(String food) {
System.out.println("学生应该吃:"+food);
}
}
public class CGLibProxy implements MethodInterceptor {
// 代理类
private Object targetObj;
public Object newInstance(Object targetObj){
this.targetObj = targetObj;
// 创建CGLib代理类
Enhancer enhancer = new Enhancer();
// 设置代理类的⽗类(⽬标类)
enhancer.setSuperclass(this.targetObj.getClass());
// 设置代理类的⽗类(⽬标类)
enhancer.setCallback(this);
// 创建子类(代理对象)
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CGLib动态代理开启-------调用方法"+method.getName());
// 调用被代理类
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("CGLib动态代理结束-------调用方法"+method.getName());
return result;
}
}
public class CGLibTest {
public static void main(String[] args) {
// 创建被代理类
Student student = new Student();
// 创建CGLib被代理类
CGLibProxy cgLibProxy = new CGLibProxy();
Student human = (Student) cgLibProxy.newInstance(student);
human.breath();
human.eat("有营养的食物");
}
}
CGLib包下载地址: https://github.com/cglib/cglib/releases?page=1
引入此包即可