程序员之Spring

1. Spring事务

spring的事务实现原理
Spring事务将connection放入到当前线程的threadlocal中,spring中使用ThreadLocal来设计TransactionSynchronizationManager类,实现了事务管理与数据访问服务的解耦,同时也保证了多线程环境下connection的线程安全问题。

2.Spring bean的作用域

类别 说明
singletone:单例 在spring中仅存在一个Bean实例,Spring默认为单例模式。
prototype:原型模式 每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态。
request:请求模式 在一次Http请求中,容器会返回该Bean的同一实例,而对不同的Http请求则会产生新的Bean,而且该bean仅在当前Http Request内有效。
session:会话模式 在一次Http Session中,容器会返回该Bean的同一实例。而对不同的Session请求则会创建新的实例,该bean实例仅在当前Session内有效。
global Session:全局会话模式 在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。

2. Spring AOP

AOP(Aspect Oriented Programing)指面向切面编程,是通过预编译和运行时动态代理实现的一种技术。

2.1 AOP 相关概念

1.连接点:join point

指Java程序中的具有边界性质的特定位置,如类初始化之前,类初始化之后,方法调用前和方法调用后等。目前Spring仅支持类方法这样的join point,可以在方法前,方法后这样的连接点织入(weaving)增强(advice)。

2.切点:point cut

AOP把类方法作为查询条件,通过point cut找到连接点(join point),即让切点来筛选连接点,如目标类有5个方法, 程序只想让3个方法实现增强,剩余的2个不需要增强,那个就通过point cut从5个方法中,筛选出需要增强的3个方法。

3.通知:advice

advice是织入到目标类方法(即join point)的程序代码块,并且制定要织入的连接点的方位(方法前,方法后等),advice主要有AfterAdvice,BeforeAdvice,ThrowAdvice,MethodInterceptor和AfterReturningAdvice等。

4.目标对象:Target

advice的增强代码织入的目标类。

5.引入:Introduction

Introduction为类添加属性或者方法,这样是一些类在没有实现某些接口的情况下,动态的添加该接口的实现。

6.织入:weaving

织入是指将advice添加到目标类方法(即连接点)上的过程,Spring采用动态代理织入,AspectJ采用编译器期间和类加载期间织入。

7.代理:proxy

目标类被织入advice后,形成一个新的代理类,该代理类同时具有目标类和advice的功能。

8.切面:Aspect

切面包含了point cut和advice组成,point cut指定了在什么地方干(指定增强的目标类方法),advice指定了干什么(增强代码块)和什么时候(before or after)干。

2.2 Java代理模式

可参考如下文章:
1.设计模式(4)-代理模式
2.Java代理(Proxy)模式

这里不再赘述。

2.3 AOP 实现原理

AOP目前有两种实现方式:
1.静态代理:静态代理可以实现编译时增强,即在程序编译阶段就生成AOP代理对象。AspectJ就是使用了静态代理的方式;
2.动态代理:动态代理可以实现运行时增强,即在程序运行时使用JDK动态代理或者Cglib代理(Code Generation Library,即代码生成包,所以也可以称为动态字节码增强代理
),临时生成AOP代理类。Spring AOP就是使用的动态代理。

2.1JDK动态代理:

JDK动态代理是针对接口的代理,只有接口方法才能够被代理,主要使用的JDK的rt.jar中的java.lang.reflect.Proxy代理类和java.lang.reflect.InvocationHandler调用程序接口。Proxy代理类内部有一个属性InvocationHandler h

package java.lang.reflect;
public class Proxy implements Serializable {
     protected InvocationHandler h;

    protected Proxy(InvocationHandler var1) {
        Objects.requireNonNull(var1);
        this.h = var1;
    }

    @CallerSensitive
    public static Class getProxyClass(ClassLoader var0, Class... var1) throws IllegalArgumentException {
       ...
       ...     
}

    @CallerSensitive
    public static Object newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h) throws IllegalArgumentException {
       ...
       ...        
    }
}

其中:
ClassLoader classLoader:指类加载器;
Class[] interfaces:获得的全部接口;
InvocationHandler h: 得到InvocationHandler接口的子类实例。

InvocationHandler.java

public interface InvocationHandler {
    /**

  */
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

其中:
Object proxy:指被代理的对象;
Method method:要调用的proxy的方法;
Object[] args: 指调用target目标类的方法的参数。

JDK动态代理的主要思路:
将InvocationHandler接口的子类封装成一个proxy的最终操作类,替换到target目标类,然后通过invoke(Object proxy, Method method, Object[] args)方法执行对target目标类的增强代码块和target目标类的方法。JDK动态代理只是在创建动态代理时,将被代理接口和InvocationHandler的实现类进行关联,当proxy执行被代理的target的方法时,通过InvocationHandler的invoke方法来执行。

JDK动态代理的缺点:
JDK动态代理的Proxy类的 public static Object newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h)方法中,interfaces限制了target必须是接口或者接口的实现。如果类没有实现接口,那么只能使用Cglib代理了。

2.2 Cglib动态代理:

Cglib动态代理采用字节码技术,为target目标类创建一个子类,Override需要被代理的方法,并在子类中采用方法拦截的技术,拦截所有父类的方法调用,然后织入advice代码块。理解Cglib代理的原理后,也就明白target目标类不能是final类,而且被代理的方法不能是private,final和static的。

Cglib动态代理主要用到了cglib-***.jar包中的net.sf.cglib.proxy.MethodInterceptor接口和net.sf.cglib.proxy.Enhancer接口,其中MethodInterceptor继承了net.sf.cglib.proxy.Callback接口,当调用代理对象方法的时候会交给callback对象的来处理。

MethodInterceptor接口:

package net.sf.cglib.proxy;

import java.lang.reflect.Method;

public interface MethodInterceptor extends Callback {
    Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy ) throws Throwable;
}

其中:
Object proxy:指子类代理对象;
Method method:要调用的方法的反射对象;
Object[] args:指传递给method的参数;
MethodProxy methodProxy:cglib生成的用来代替method对象的。

Cglib的核心是实现MethodInterceptor接口,使用intercept()方法进行面向切面的处理,调用相应的增强advice。

2. Spring IOC

你可能感兴趣的:(程序员之Spring)