美文网首页
程序员之Spring

程序员之Spring

作者: zhglance | 来源:发表于2019-05-30 15:17 被阅读0次

    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

          本文链接:https://www.haomeiwen.com/subject/sslvtctx.html