spring

Spring 的AOP 实现原理

Spring 的 AOP 实现原理其实很简单,就是通过动态代理实现的。
如果我们为Spring的某个bean配置了切面,那么Spring在创建这个bean的时候,实际上创建的是这个bean的一个代理对象,我们后续对bean中方法的调用,实际上调用的是代理类重写的代理方法。
Spring的AOP使用了两种动态代理,分别是 JDK 的动态代理,以及 CGLib 的动态代理。
JDK动态代理:
Spring 默认使用JDK的动态代理实现AOP,类如果实现了接口,Spring就会使用这种方式实现动态代理。
JDK 实现动态代理需要两个组件,首先第一个就是InvocationHandler接口。我们在使用JDK的动态代理时,需要编写一个类,去实现这个接口,然后重写invoke方法,这个方法其实就是我们提供的代理方法。
然后JDK动态代理需要使用的第二个组件就是Proxy这个类,我们可以通过这个类的newProxyInstance方法,返回一个代理对象。生成的代理类实现了原来那个类的所有接口,并对接口的方法进行了代理,我们通过代理对象调用这些方法时,底层将通过反射,调用我们实现的invoke方法。
CGLib动态代理:
JDK的动态代理存在限制,那就是被代理的类必须是一个实现了接口的类,代理类需要实现相同的接口,代理接口中声明的方法。若需要代理的类没有实现接口,此时JDK的动态代理将没有办法使用,于是Spring会使用CGLib的动态代理来生成代理对象。CGLib直接操作字节码,生成类的子类,重写类的方法完成代理。
aop 在私有方法上不生效,在final方法上不生效,在同一个类内部互相调用不生效,在静态方法上不生效,归根到底在于aop的实现依赖于代理类继承自原有类,非public方法都无法继承。

SPI

SPI 机制 SPI机制最大的好处在于也就是与API 的区别,在于实现类的输出由谁来负责,API 机制由接口提供者实现,多用于具体多业务实现,而SPI 机制则是由使用的人来实现,通常SPI 只要用来规范处理流程,而具体的处理内容则由使用的人来实现,多用于框架中。

@Autowired和@Resource的区别

共同点:二者都可以写在字段和setter方法上。
区别:

  • @Autowired 为Spring 提供的注解,按照byType 注入,默认情况下依赖对象必须存在,如果允许null 值,则要设置required 属性为false。如果要按照名称byName 来装配,则需要搭配@Qualifer 注解一起使用。
  • @Resource 由J2EE 提供,默认按照byName 装配,其有两个属性:name 和type,将@Resource 的name 属性解析为bean 的名称,而type 为解析的类型。如果既不指定name 也不指定type 则通过反射机制使用byName 自动注入。