欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring笔记 SpringBean正则表达式配置管理AOP 

程序员文章站 2024-02-14 09:34:10
...
Spring笔记
                                      

1.一个bean默认的方式是singleton="true"
2.<ref bean="xxx">和<ref local="xxx">有差别, 后者表示从本地的(同一个)xml文件中来寻找bean
3.abstract和parent的用法。
如果有很多的bean的某些定义都是类似的(比如对于transaction的定义),那么可以给他们的定义作一个模板。
使用parent可以实现这一点。(注意parent并非意味着两个bean之间存在着java的继承关系,只是表示他们的定义之间存在着共同的部分)。
child bean使用parent来继承模板的定义,同样还可以覆盖模板的定义。


<bean id="inheritedTestBean" abstract="true"
    class="org.springframework.beans.TestBean">
    <property name="name"><value>parent</value></property>
    <property name="age"><value>1</value></property>
</bean>


<bean id="inheritsWithDifferentClass" class="org.springframework.beans.DerivedTestBean"
      parent="inheritedTestBean" init-method="initialize">
    <property name="name"><value>override</value></property>
    <!-- age should inherit value of 1 from parent -->
</bean>


很多时候模板并不需要被实例化,为了避免ApplicationContext对它预先的初始化,一般设置abstract="true"


4.ApplicationContext和BeanFactory的区别
生命周期:ApplicationContext会预先初始化所有的singleton的实例


5.transaction
<!-- this example is in verbose form, see note later about concise
     for multiple proxies! -->
<!-- the target bean to wrap transactionally -->
<bean id="petStoreTarget">
  ...
</bean>
<bean id="petStore"
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager"><ref bean="transactionManager"/></property>
    <property name="target"><ref bean="petStoreTarget"/></property>
    <property name="transactionAttributes">
        <props>
            <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
            <prop key="update*">PROPAGATION_REQUIRED</prop>
            <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
        </props>
    </property>
</bean>


6.
     <bean id="UserManager"
  class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target">
   <ref local="UserManagerTarget" />
  </property>
  <property name="interceptorNames">
   <list>
    <value>debugAdvice</value>
    <value>AfterAdvice</value>
   </list>
  </property>
</bean>
      对interceptorNames进行配置的时候,可以是一个配置一个advisor, 还是是一个advice.
7.advice跟advisor的区别:
advice:它是interceptor, 类型是Around, After, Before, Throw类型中的一种。
        advisor:advisor也是interceptor,从某种意义上,可以理解它也是一种advice,却可以对一个对象的方法进行过滤。符合某些条件的方法该interceptor才生效。
比如RegexpMethodPointcutAdvisor就可以进行正则表达式的配置。get.*表示该interceptor只对getxxx的方法有效。


8.Spring 的AOP 的Advice基本上都是基于class来进行配置的, 例如上面的那个UserManager, 就是对UserManagerTarget对应的那个类来进行配置的。
如何对很多类都进行类似的配置呢?可以使用第三点说到的template来实现。但是这种方法实质上还是对每个单独的类进行配置。
到底怎么做才可以是针对每个对象来配置的呢?


9.Spring的事务管理的大致实现如下:
关键类和方法:
org.springframework.transaction.interceptor.TransactionInterceptor.invoke
org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary
org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction


事务管理只有一个interceptor,那就是TransactionInterceptor。它在对象调用的每个方法之前都会检查一下是否有必要新建一个transaction
createTransactionIfNecessary用来检查是否有必要新建一个transaction。
步骤如下:
寻找transactionAttributes中是否定义有匹配的方法名,匹配包括完全匹配和正则匹配.(优先寻找完全匹配)
1。如果发现定义中有匹配的定义,则
2。从ThreadLocal中找到connectionHoler对象,该对象是在DataSourceUtil.getConnection(DataSource)中获得的。这就是为什么要使用DataSourceUtil.getConnection(DataSource)
的原因。一个connectionHolder对象里边记录了被请求的次数。
3。检查当前的Transaction是否存在?即查找ThreadLocal里边的connectionHolder是否存在,如果存在,表示Transaction已经存在,直接返回。
4。如果当前的Transaction在ThreadLocal中不存在,那么调用DataSourceTransactionManager.doBegin()方法。来新建一个transaction.



10.<property name="transactionAttributes">
   <props>
    <prop key="insert*">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
定义的时候只有如果方法执行的时候发生了RuntimeException, 那么Spring会会滚。
如果发生了非RuntimeException,那么Spring还是会提交的。
如果要在Exception的时候也想回滚,那么应该写上<prop key="insert*">PROPAGATION_REQUIRED, -java.lang.Exception</prop>