静态代理和动态代理
字面含义:
静态代理:静止的,静态的,不会发生改变的,在编译期间已经写好的。
动态代理:动态的,会发生变化的,在编译期间无法确定的。
先观看代码,然后查看代码的区别(动态代理分为jdk动态代理和cglib的动态代理,jdk的动态代理主要是实现接口,cglib的动态代理主要是通过继承;由于继承是单继承的方式,局限性低一般采用jdk的动态代理)
代理目标类接口实现类,实现userService,peopleService接口
public class ServiceImpl implements UserService, PeopleService { @Override public void addUser() { System.out.println("新增用户信息"); } @Override public void isPerson() { System.out.println("是一个人"); } }
UserService接口
public interface UserService { /** * 新增用户 */ void addUser(); }
PeopleService接口
public interface PeopleService { /** * 是一个人 */ void isPerson(); }
1. 静态代理
public class StaticProxyUserService implements UserService{ private UserService userService; public StaticProxyUserService(UserService userService) { this.userService = userService; } @Override public void addUser() { System.out.println("--- 静态代理开始了 ---"); userService.addUser(); System.out.println("--- 静态代理结束了 ---"); } }
public class StaticProxyPeopleService implements PeopleService { private PeopleService peopleService; public StaticProxyPeopleService(PeopleService peopleService) { this.peopleService = peopleService; } @Override public void isPerson() { System.out.println("--- 静态代理开始了 ---"); peopleService.isPerson(); System.out.println("--- 静态代理结束了 ---"); } }
发现,静态代理,对应每一个接口,都得写一个代理类(也可以只写一个代理类实现多个接口,但是需要重写多个方法)
2. 动态代理
public class DynamicProxyService implements InvocationHandler { private Object target; public DynamicProxyService(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("---动态代理开始了---"); Object object = method.invoke(target, args); System.out.println("---动态代理结束了---"); return object; } public Object getProxyObject(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } }
发现动态代理简单,只需要写一个通用代理处理器,重写invoke方法就行。然后通过Proxy类获取代理对象,不用再写多余的代码,对于实现了多个接口的多个方法,或者一个接口中的多个方法进行相同的业务逻辑代理的时候,十分简洁。
其实间言一句话,静态代理,需要在代理逻辑中指明具体代理了那个接口的哪个方法,比如在指明了userService.addUser方法;而动态代理,不需要指明,只需重写invoke方法,Method.invoke方法会动态的找到我们要代理的方法,不用像静态代理那样需要一个个去指定。

浙公网安备 33010602011771号