静态代理模式
结构图:
- 接口
public interface Eat {
public void eat();
}
- 真实类A
public class EatImpl implements Eat {
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
- 真实类B
public class EatImpl2 implements Eat {
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
- 工厂
public class Factory {
public static Eat factory(String animal){
if("cat".equals(animal)){
return new EatImpl();
}else if("dog".equals(animal)){
return new EatImpl2();
}
return null;
}
}
- 核心:代理类
public class Proxy implements Eat {
private Eat eat;
public Proxy(String animal){
this.eat = Factory.factory(animal);
}
private void start(){
System.out.println("准备食物");
}
private void end(){
System.out.println("收拾");
}
@Override
public void eat() {
this.start();
this.eat.eat();
this.end();
}
}
- 测试类
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String next = sc.next();
Proxy p = new Proxy(next);
p.eat();
}
}
动态代理
第一步:创建Dao接口
public interface EatDao {
public void eat();
public void drink();
}
第二步:实现Dao接口
public class EatImpl implements EatDao {
@Override
public void eat() {
System.out.println("吃饭");
}
@Override
public void drink() {
System.out.println("喝酒");
}
}
第三步:创建事务类,切面类
public class MyTransaction {
public void prepare(){
System.out.println("开启事务");
}
public void after(){
System.out.println("关闭事务");
}
}
第四步:代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ObjectInterceptor implements InvocationHandler {
//目标类
public EatDao eat;
//切面类
public MyTransaction myTransaction;
public ObjectInterceptor(EatDao eat, MyTransaction myTransaction) {
this.eat = eat;
this.myTransaction = myTransaction;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
this.myTransaction.prepare();
method.invoke(this.eat,args);
this.myTransaction.after();
return null;
}
}
第五步:测试类
public void test1(){
//要代理的真实类
EatDao eat = new EatImpl();
//切面类对象
MyTransaction myTransaction = new MyTransaction();
ObjectInterceptor objectInterceptor = new ObjectInterceptor(eat, myTransaction);
/**
* 通过proxy类的newProxyInstance方法创建代理对象
* 第一个参数:eatImpl2.getClass().getClassLoader(),使用objectInterceptor对象的classloader对象来加载我们的代理对象
* 第二个参数:eatImpl2.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口
* 中的所有方法
* 第三个参数:objectInterceptor,我们将代理对象关联到上面的事务类中
*/
EatDao o = (EatDao) Proxy.newProxyInstance(eat.getClass().getClassLoader(), eat.getClass().getInterfaces(), objectInterceptor);
o.drink();
o.eat();
}
动态代理和静态代理的区别
- 静态代理的代理类实现的是Dao层的接口,动态代理的代理类实现的是java.lang.reflect.InvocationHandler这个接口
- Dao层接口发生变化,静态代理代理类需要进行相应的改变,而动态代理的代理类不需要进行任何改变