首先来说静态代理:静态代理,是要为每一个需要代理的类生成一个对象,假如有一万个类,那么就要写1万个代理,这是非常恐怖的。下面是静态代理的实现;
代理和目标都要实现相同的接口:
- /**
- * 代理和目标类都要实现的接口
- * @author real
- *
- */
- public interface PersonInterface {
- void getName();
- }
复制代码
目标类:- /**
- * 需要被代理的类,目标类
- * @author real
- *
- */
- public class Person implements PersonInterface{
- @Override
- public void getName() {
- System.out.println("Person getName 执行");
- }
- }
复制代码 代理类:- public class PersonProxy implements PersonInterface{
- private PersonInterface person;
-
- public PersonProxy(PersonInterface person) {
- this.person = person;
- }
-
- @Override
- public void getName() {
- //在执行目标的真实方法之前,可以做其他事情,例如记录日志等。
- System.out.println("PersonProxy 的getName方法执行");
- //执行真实的目标类方法
- person.getName();
- }
- }
复制代码 测试类:
- public class PersonTest {
-
- public static void main(String[] args) {
- //真实的Person
- PersonInterface person = new Person();
- //Person的代理,需要把Person穿进去
- PersonInterface personProxy = new PersonProxy(person);
-
- //直接调用person的方法
- person.getName();
- //通过代理调用person的方法
- personProxy.getName();
- }
- }
复制代码 以上代码就是实现静态代理的方法,上面的问题就是如果需要代理的类太多,就得用到了动态代理。在jdk中可以动态的生成代理类。
下面是一个动态代理类:
- public class Proxy1 {
- private Object target;
-
- //将需要被代理的类通过对象传入进来
- public Proxy1(Object target) {
- this.target = target;
- }
-
- /**
- * 通过jdk的Proxy动态的生成target的代理类。
- * @return
- */
- public Object getProxy() {
-
- /**
- * Proxy.newProxyInstance()方法需要的三个参数分别问,这个代理类的ClassLoader,
- * 这个类所有实现的接口,还有一个InvocationHandler,所有的代理方法都要通过里面的invoke方法,
- * 然后我们可以在invoke方法内部调用target的真实方法,还可以执行其他代码
- */
- return Proxy.newProxyInstance(target.getClass().getClassLoader(),
- target.getClass().getInterfaces(),
- new InvocationHandler() {
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- //retVal就是目标对象方法执行后的返回值
- System.out.println("动态代理类。记录日志");
- Object retVal = method.invoke(target, args);
- return retVal;
- }
- });
- }
- }
复制代码
测试代理类:
- Proxy1 p1 = new Proxy1(person);
- PersonInterface personProxy1 = (PersonInterface) p1.getProxy();
- personProxy1.getName();
复制代码
有了动态代理,就可以代理任何你传入的对象了。不会像静态代理一样限制类型了。
|