代理模式(proxy)是指为其他对象提供一种代理,以控制这个对象的访问,该代理对象作为访问对象和目标对象之间的中介
1.静态代理
/**
* 代理接口
*/
interface IAnimal {
/**
* 运动
*/
void motion();
}
public class Cat implements IAnimal {
@Override
public void motion() {
System.out.println("cat motion");
}
public static void main(String[] args) {
IAnimal cat=new Cat();
// 静态代理对象调用
AnimalProxy animalProxy =new AnimalProxy(cat);
animalProxy.motion();
}
}
/**
* 静态代理类
* 优点:
* 业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。
* 缺点:
* 代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
* 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度
*/
public class AnimalProxy implements IAnimal {
private IAnimal animal;
@Override
public void motion() {
System.out.println("动物运动前准备...");
animal.motion();
System.out.println("动物运动后操作...");
}
public AnimalProxy(IAnimal animal) {
this.animal = animal;
}
}
2.动态代理
想要了解原理>>>传送门
interface IAnimal {
/**
* 运动
*/
void motion();
}
public class Cat implements IAnimal {
@Override
public void motion() {
System.out.println("cat motion");
}
public static void main(String[] args) {
IAnimal cat = new Cat();
IAnimal tomHandle = new AnimalInvocationHandle().getObject(cat);
tomHandle.motion();
}
}
/**
* 动态代理对象 实现 InvocationHandler 接口
* 底层实现 根据发射编写.java文件,编译文件,jvm加载文件,使用后销毁
*
* 优点:
* 动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。
* 这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。在本示例中看不出来,
* 缺点:
* 目标对象一定要实现接口,否则不能使用动态代理
*/
public class AnimalInvocationHandle implements InvocationHandler {
private Object object;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("调用前操作...");
method.invoke(object, args);
System.out.println("调用后操作...");
return object;
}
public IAnimal getObject(IAnimal user){
this.object=user;
return (IAnimal)Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
}
3.cglib代理
public class Cat {
public void motion() {
System.out.println("猫---运动");
}
public static void main(String[] args) {
Cat cat = new Cat();
AnimalFactory animalFactory = new AnimalFactory(cat);
Cat cglibProxy = (Cat) animalFactory.getCglibProxy();
cglibProxy.motion();
}
}
/**
* cglib代理
*
* JDK动态代理机制只能代理实现接口的类,一般没有实现接口的类不能进行代理。cglib就是针对类来实现代理的,它
* 的原理是对指定目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
*
* 使用cglib实现动态代理,完全不受代理类必须实现接口的限制,而且cglib底层采用ASM字节码生成框架,使用字节码技术生成代理类,
* 比使用java反射效率要高。
* 需要引入两个jar包:cglib.jar,asm.ja
*/
public class AnimalFactory {
private Object object;
public AnimalFactory(Object object) {
this.object = object;
}
public Object getCglibProxy(){
//实例化一个增强器,也就是cglib中的一个class generator
Enhancer enhancer = new Enhancer();
//设置目标类
enhancer.setSuperclass(this.object.getClass());
//设置拦截对象
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("准备...");
methodProxy.invokeSuper(o,objects);
return null;
}
});
//生成代理类并返回一个实例
return enhancer.create();
}
}