版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/LMD802/article/details/83934005
代理模式
代理模式分为动态代理和静态代理
就是在不修改原代码的基础上,
对原对象进行功能增强
1.静态代理
- 1.1 要有接口
- 1.2 遍写接口实现类
- 1.3 编写代理类,也去实现被代理对象实现的接口
- 缺点:
- 1.只能代理一类对象,代理类只能代理实现了被代理对象实现的接口
- 2.代理对象固定
/**
* 接口
* @author 落幕
*/
public interface Work {
void work();
}
/**
* 接口实现类
* @author 落幕
*
*/
public class Programer implements Work {
@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("Coding...");
}
}
/**
* 接口实现类
* @author 落幕
*/
public class Sell implements Work {
@Override
public void work() {
// TODO Auto-generated method stub
System.out.println("Selling...");
}
}
/**
* 静态代理类
* @author 落幕
*
*/
public class StaticProxy implements Work {
private Object target;
//提供有参构造
public StaticProxy(Object target) {
super();
this.target = target;
}
@Override
public void work() {
// TODO Auto-generated method stub
//其引用要为接口
Work work = (Work) target;
work.work();
}
public static void main(String[] args) {
//Programer pro = new Programer();
Sell sell = new Sell();
StaticProxy factory = new StaticProxy(sell);
factory.work();
}
}
动态代理
JDK动态代理:java.lang.reflect.Proxy
- 被代理的对象必须有接口:Class<?>[] interfaces = cls.getInterfaces();因为他需要通过接口创建引用
- 如果一个类有接口,spring默认使用JDK动态代理创建该类实例
- 注意:
- 1.JDK动态代理创建的对象只能强转为接口类型,不能强转为实现类类型
- 2.对象有接口,在SpringDI中只能使用接口类型进行注入
/**
* 接口
* @author 落幕
*/
public interface Actor {
void Act();
}
/**
* 接口实现类
* @author 落幕
*/
public class LikeActor implements Actor {
@Override
public void Act() {
// TODO Auto-generated method stub
System.out.println("喜欢的男演员:胡歌");
}
}
/**
* 接口实现类
* @author 落幕
*/
public class LikeActress implements Actor {
@Override
public void Act() {
// TODO Auto-generated method stub
System.out.println("喜欢的女演员:林依晨");
}
}
public class JDKProxy {
private Object target;
public JDKProxy(Object target) {
super();
this.target = target;
}
public Object createObject() {
// TODO Auto-generated method stub
//1.获取类对象
Class<?> cls = target.getClass();
//2.获取类加载器
ClassLoader loader = cls.getClassLoader();
//3.获取该对象实现的所有接口
Class<?>[] interfaces = cls.getInterfaces();
return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
//invoke():代理对象执行方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//通过反射调用方法:
//Method.invoke(对象名,方法参数列表):Object
return method.invoke(target, args);
}
});
}
public static void main(String[] args) {
Programer pro = new Programer();
JDKProxy proxy = new JDKProxy(pro);
//要用接口做引用
Work worker = (Work) proxy.createObject();
worker.work();
System.out.println("-------------------");
LikeActor actor = new LikeActor();
proxy = new JDKProxy(actor);
Actor act = (Actor) proxy.createObject();
act.Act();
}
}
cglib动态代理:
- 被代理的对象无需实现任意接口, 使用spring无需导入cglib.jar
spring默认整合了cglib - 优点:
可以实现对任意对象的动态代理
/**
* 接口
* @author 落幕
*/
public class CglibProxyFactory {
private Object target;
public CglibProxyFactory(Object target) {
super();
this.target = target;
}
/**
* 创建代理对象
* @return
*/
public Object createProxyObject(){
//Enhance:提高,增强
//1.创建代码增强工具对象
Enhancer enhancer = new Enhancer();
//2.指定被代理对象为代理对象的父类
enhancer.setSuperclass(target.getClass());
//3.编写代理对象的执行方法
//MethodInterceptor是Callback的子接口
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object arg0, Method method, Object[] params, MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
//value:原对象方法执行的返回值
Object value = method.invoke(target, params);
return value;
}
});
//4.创建被代理对象
return enhancer.create();
}
public static void main(String[] args) {
LikeActress actress = new LikeActress();
CglibFactory proxy = new CglibFactory(actress);
//可以没有接口
LikeActress actre = (LikeActress) proxy.createObject();
actre.act();
}
}
注意:
类有接口,spring使用JDK动态代理创建对象
类无接口,spring使用cglib动态代理创建对象