Java动态代理是一种在运行时生成代理对象的技术,它可以无需编写具体的代理类代码,通过一组接口和实现类,动态的生成相应的代理类,从而实现对目标对象的代理操作。使用动态代理,可以在不修改原有类的前提下,对类的某些方法进行增强或者加入其他的逻辑。
下面是Java动态代理的使用攻略,包含以下步骤:
第一步:编写接口
首先,需要编写一个接口类,该接口类包含原有类的方法以及需要动态代理处理的方法。
public interface People {
void eat();
void sleep();
void work();
void study();
void play();
}
第二步:编写目标类
接着,需要编写目标类,该类实现上面的接口,并实现其中的方法。
public class PeopleImpl implements People {
@Override
public void eat() {
System.out.println("eat...");
}
@Override
public void sleep() {
System.out.println("sleep...");
}
@Override
public void work() {
System.out.println("work...");
}
@Override
public void study() {
System.out.println("study...");
}
@Override
public void play() {
System.out.println("play...");
}
}
第三步:编写代理类
接下来,需要编写代理类,在代理类中,我们需要实现InvocationHandler接口,并重写其中的invoke()方法。在该方法中,我们可以调用原有类中的方法,也可以对该方法进行增强或加入其他逻辑。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class PeopleProxy implements InvocationHandler {
private Object target;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理类执行方法:" + method.getName());
Object result = method.invoke(target, args);
System.out.println("方法执行结束");
return result;
}
}
第四步:使用代理类
最后,我们需要使用代理类来完成对目标类的代理操作。
public class Test {
public static void main(String[] args) {
People people = new PeopleImpl();
PeopleProxy proxy = new PeopleProxy();
People peopleProxy = (People)proxy.bind(people);
peopleProxy.eat();
peopleProxy.sleep();
peopleProxy.study();
}
}
在上述代码中,我们首先实例化了原有类PeopleImpl和代理类PeopleProxy。接着,我们通过代理类的bind()方法获取到代理对象peopleProxy。最后,在使用代理对象的方法时,代理类的invoke()方法就会被调用,从而实现了对原有类方法的代理。在这里,我们对代理类的invoke()方法进行了增强,在原有方法执行前后输出一些字符串。
示例2:
public interface Calculator {
int add(int a, int b);
int sub(int a, int b);
}
public class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
@Override
public int sub(int a, int b) {
return a - b;
}
}
public class CalculatorProxy implements InvocationHandler {
private Object target;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理类执行方法:" + method.getName() + "(" + args[0] + "," + args[1] + ")");
Object result = method.invoke(target, args);
System.out.println("方法执行结束,结果为:" + result);
return result;
}
}
public class Test {
public static void main(String[] args) {
Calculator calculator = new CalculatorImpl();
CalculatorProxy proxy = new CalculatorProxy();
Calculator calculatorProxy = (Calculator)proxy.bind(calculator);
int a = 10, b = 5;
int res1 = calculatorProxy.add(a, b);
int res2 = calculatorProxy.sub(a, b);
System.out.println("计算结果 res1:" + res1);
System.out.println("计算结果 res2:" + res2);
}
}
在这个示例中,我们使用了另一个接口Calculator和实现类CalculatorImpl,使用代理类CalculatorProxy对CalculatorImpl进行了代理操作。在代理类中,我们使用了反射技术和动态代理生成了代理对象,并在该对象的方法中增加了输出字符串的操作。在最后的代码中,我们对代理对象的方法进行了多次调用,以便验证代理类Proxy的效果。
综上所述,Java动态代理是一种在运行时生成代理对象的技术,可以在不修改原有类的前提下,对类的某些方法进行增强或者加入其他的逻辑。