重点等级::star::star::star::star::star:
代理既间接对目标对象进行访问的方式;即通过代理对象访问目标对象。
可以在目标对象实现的功能上,增加额外的功能补充,也可以对目标对象进行一些限制等扩展。
- 访问控制
- 代理服务器Apache Commons Proxy 代理服务器
- Mocking frameworks Mockito, Powermock, EasyMock 框架 Mockito,Powermock,EasyMock
- Spring AOP 面向切面编程。可以在指定方法中切一刀添加新的逻辑。
在使用静态代理时,被代理对象与代理对象需要一起实现相同的接口或者是继承相同父类,因此要定义一个接口或抽象类.
// 接口
interface IStar {
void sing();
}
// 被代理对象
class LDHStar implements IStar {
@Override
public void sing() {
System.out.println("刘德华唱歌");
}
}
// 代理类
class ProxyManger implements IStar {
// 真实对象的引用
private IStar star;
public ProxyManger() {
super();
}
public ProxyManger(IStar star) {
super();
this.star = star;
}
@Override
public void sing() {
//TODO 唱歌前准备工作
System.out.println("唱歌前准备");
star.sing();
System.out.println("善后工作");
}
}
class ProxyDemo{
public static void main(String[] args) {
// 创建明星对象
IStar ldh = new LDHStar();
ProxyManger proxy = new ProxyManger(ldh);
proxy.sing();
}
}
优点:可以做到在不修改目标对象的功能前提下,对目标功能扩展。
缺点:因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护。
动态代理的主要特点就是能够在程序运行时JVM才为被代理对象生成代理对象。
常说的动态代理也叫做JDK代理也是一种接口代理java.lang.reflect.Proxy
,JDK中生成代理对象的代理类就是Proxy
//同样引用上面代码中的 接口 与 被代理对象
class MyInvocationHandle implements InvocationHandler{
private Object target;
public void setTarget(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//TODO 唱歌前准备工作
System.out.println("唱歌前准备");
method.invoke(target, args);
System.out.println("善后工作");
return null;
}
}
//生产代理对象的工厂
class MyProxyFactory{
public static Object getProxy(Object target) {
MyInvocationHandle handle = new MyInvocationHandle();
handle.setTarget(target);
//JDK 生产代理对象
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),handle);
return proxy;
}
}
public class ProxyDemo {
public static void main(String[] args) {
IStar ldh = new LDHStar();
IStar proxy =(IStar) MyProxyFactory.getProxy(ldh);
proxy.sing();
}
}
代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能使用动态代理。
静态代理和动态代理模式都要求目标对象是实现一个接口的对象。
如何对没有实现接口的对象进行代理?那就是 cglib
Cglib代理:使用继承目标类以目标对象子类的方式实现代理,叫作子类代理。它是在内存中构建一个子类对象从而实现对目标对象功能的扩展。
最典型的就是 Spring AOP 动态代理也使用了 cglib