spring学习笔记

spring IOC容器就是普通的JavaBean,只是它提供了一些特殊功能,它可以存放其他的对象,而且提供了访问路径。我们可以将IOC容器理解为BeanFactory或者ApplicationContextBeanFactoryIOC容器的底层实现,ApplicationContext是建立在BeanFactory之上的。BeanFactory需要一个Resource来加载配置文件,其中Resource有两种实现方式:ClassPathResource从类路径加载资源,FileSystemResource从文件系统加载资源。ApplicationContext加载配置文件的方式有两种:ClassPathXmlApplicationContextFileSystemXmlApplicationContext

spring使用配置文件来描述bean与bean之间的关系,并且由IOC容器来实例化这些bean。IOC容器在装配bean的时候,先调用构造函数创建一个对象,然后通过反射调用对象的各个set方法为对象的属性赋值,最后这个bean会被缓存起来等待被使用。

bean的配置:

(1)属性注入。

<bean id="myBook" class="model.Book">

<property name="id" value="000001"/>

</bean>

需要注入的属性在类中必须有set方法,必须有默认的构造函数,尤其当类中有一个显性的非默认构造函数,这时,必须再重新添加一个默认构造函数。

(2)bean的依赖关系。

<bean id="dt" class="java.util.Date"></bean>

<bean id="person" class="model.Person">

<property name="name" value="zhao">

<property name="birthday" ref="dt"/>

</bean>

3)集合的注入。

有一个类JavaBookStore

package model;

import java.util.*;

public class JavaBookStore{

private List commonBooks;

private Set favorites;

private Map publisherMappings;

private HashMap<String,String> gysInfor;

public List getCommonBooks(){

return commonsBooks;

}

public void setCommonBooks(List commonBooks){

this.commonBooks = commonBooks;

}

public Set getFavorites(){

return favorites;

}

public void setFavorites(Set favorites){

this.favorites = favorites;

}

public Map getPublisherMappings(){

return publisherMappings;

}

public void setPublisherMappings(Map publisherMappings){

this.publisherMappings = publisherMappings;

}

public HashMap<String,String> getGysInfor(){

return gysInfor;

}

public void setGysInfor(HashMap<String,String>gysInfor){

this.gysInfor= gysInfor;

}

则配置如下:

<bean id="javaBookStore" class="model.JavaBookStore">

<property name="commonBooks">

<list>

<ref bean="myBook1"/>

<ref bean="myBook2"/>

<ref bean="myBook3"/>

</list>

</property>

<property name="favorites">

<set>

<ref bean="myBook1"/>

<ref bean="myBook2"/>

<ref bean="myBook3"/>

</set>

</property>

<property name="publisherMappings">

<map>

<entry key="phei" value="Publishing House of Electronics Industry"/>

<entry key="cmp" value="China machine Press"/>

<entry key="ptp" value="Post and TeleCOM Press"/>

<entry key-ref="myBook1" value-ref="myBook1"/>

<entry key="rmrb">

<ref bean="myBook2">

</entry>

</map>

</property>

<property name="gysinfor">

<props>

<prop key="name">wangli</prop>

</props>

</property>

</bean>

4bean的作用域。

bean有五种作用域:singleton,prototype,request,session,globalSession,其中后面三种在WebApplicationContext中才有效,默认的作用域为singletonsingleton只会实例化一次,singletonbean还可以指定lazy-init属性,<bean id="dt" class="java.util.Date" lazy-init="true"></bean>表示只有用到bean的时候才实例化。

IOC容器的高级特性涉及到属性编辑器,使用外部属性文件,国际化,容器事件等。

1)属性编辑器的作用就是将配置文件中字面量转换为bean的属性对应的类型,spring为基本的数据类型包括包装类型、集合类型(List,Set,Map,Collection)、资源类型(File,Class,Local,Resource,InoutStream,URL)提供了默认的属性编辑器。

2)我们经常把数据库连接用的用户名、密码单独放在一个properties文件中,但是我们希望在bean的配置文件中使用它,例如db.properties文件如下:

jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver

jdbc.url=jdbc:microsoft:sqlserver://localhost:2431

jdbc:username=sa

jdbc.password=123456

该文件放在classpath下面根目录下,我们需要把这个属性文件也注册到IOC容器:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="locations">

<list>

<value>classpath:db.properties</value>

</list>

</property>

</bean>

配置一个DataSource并且使用这个属性文件:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">

<property name="driverClassName" value="${jdbc.driverClassName}"/>

<property name="url" value="${jdbc.url}"/>

<property name="username" value="${jdbc.username}"/>

<property name="password" value="${jdbc.password}"/>

</bean>

Sping AOP的目的就是要把和核心逻辑无关的却又无法消除的代码(比如事物控制代码)从核心代码中剥离出来,使业务逻辑类专注于业务逻辑,并且在适当的时候(比如运行时)再把他们植入到核心业务代码中。

1)增强(Advice

把性能监测和事物控制的逻辑除掉之后,如果想继续使用性能监测和事物控制,则要做两件事情:

一是创建增强Advice,把性能监测和事物控制的代码放到增强里面;二是用一种灵活的方式把增强植入到干净的业务实现类中。Spring提供了前置增强MethodBeforeAdvice、后置增强AfterReturningAdvice、环绕增强MethodInterceptor、异常抛出增强ThrowsAdvice等。一个前置增强的例子:

package aop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BookServiceBeforeAdvice implements MethodBeforeAdvice{

public void before(Method method,Object[] args,Object obj) throws Throwable{

System.out.println("advice before method" +obj.getClass().getName() + "." + method.getName() + "().");

}

}

通过代理工厂ProxyFactoryAdvice植入到目标对象BookService并且产生代理对象。

package aop;

import model.Book;

import org.springframework.aop.BeforeAdvice;

import org.springframework.aop.framework.ProxyFactory;

public class TestAdvice{

public static void main(String[] args){

BookService target = new BookServiceImpl();

BeforeAdvice advice = new BookServiceBeforeAdvice();

ProxyFactory pf = new ProxyFactory();

pf.setTarget(target);

pf.addAdvice(advice);

BookService service = (BookService)pf.getProxy();

service.insertBook(new Book());

service.removeBook(new Book());

}

}

一个后置增强的例子:

package aop;

impport java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class BookServiceAfterReturningAdvice implements AfterReturningAdvice{

public void afterReturning(Object returnObj,Method method,Object[] args,Object target) throws Throwable{

System.our.println("method " + target.getClass().getName() + "." + method.getName() + "() has beean executed.");

}

}

一个环绕增强的例子:

package aop;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

public class BookServcieInterceptor implements MethodInterceptor{

public Object invoke(MethodInvocation invocation) throws Throwable{

Object[] args = invocation.getArguments();//获取目标方法参数

System.out.println("the method " + invocation.getThis().getClass().getName() + "." + invocation.getMethod().getName() + "() will be

executed.");

Object obj = invocation.proceed();//执行目标方法

Ssystem.out.println("the method " + invocation.getThis().getClass().getName() + "." + invocation.getMethod().getName() + "() has been

executed.");

return obj;

}

}

上面的各种增强可以通过配置文件来实现:

<bean id="beforeAdvice" class="aop.BookServiceBeforeAdvice"/>

<bean id="afterAdvice" class="aop.BookServiceAfterReturningAdvice"/>

<bean id="interceptor" class="aop.BookServiceInterceptor"/>

<bean id="targetService" class="aop.BookServiceImpl"/>

<bean id="bookService" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces">

<values>aop.BookServcie</value>

</property>

<property name="interceptorNames">

<list>

<value>beforeAdvice</value>

<value>afterAdvice</value>

<value>interceptor</value>

</list>

</property>

<property name="targetName">

<value>targetService</value>

</property>

</bean>

2)切面

增强作用于一个类的所有方法,也就是说增强不能定位到具体的方法,但有的时候我们只希望某些方法得到增强,比如有一个BookService,它有

insertBook,updateBook,deleteBook,getAll,findById等方法,但是只需要对insert,update,delete开头的方法开启事物,那就需要用到切面。切面包含增

强,同时还包括一个方法匹配器。切面有动态切面和静态切面,下面是一个静态正则表达式方法匹配切面的用法:

<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

<property name="patterns">

<list>

<value>insert*</value>

<value>remove*</value>

</list>

</property>

<property name="advice" ref="beforeAdvice"/>

</bean>

<bean id="bookService" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces">

<values>aop.BookServcie</value>

</property>

<property name="interceptorNames">

<list>

<value>beforeAdvice</value>

<value>afterAdvice</value>

<value>interceptor</value>

<value>regexpAdvisor</value>

</list>

</property>

<property name="targetName">

<value>targetService</value>

</property>

</bean>

spring事物管理

(1)spring事物管理的第一种配置方式:为每一个目标bean配置一个代理

<bean id="companyDao" class="dao.hibernate.CompanyDaoImpl">

  <property name="hibernateTemplate" ref="hibernateTemplate"/>

</bean>

<bean id="companyServiceTarget" class="services.CompanyServcie">

   <property name="companyDao" ref="companyDao"/>

</bean>

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

  <property name="dataSource" ref="dataSource"/>

</bean>

<bean id="companyService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

    <property name="transactionManager" ref="txManager"/>

   <property name="target" ref="companyServiceTarget"/>

   <property name="optimize" value="true"/><!-- optimize可选,true代表使用CGLib,false代表使用jdk proxy --> 

   <property name="transactionAttributes">

        <props>

                <prop key="insert*">PROPAGATION_REQUIRED</prop>

                <prop key="update*">PROPAGATION_REQUIRED</prop>

                <prop key="delete*">PROPAGATION_REQUIRED</prop>

                <prop key="list">PROPAGATION_REQUIRED,readOnly</prop>

         </props> 

    </property>

</bean>

(2)spring事物管理的第二种配置方式:目标bean共享代理基类

<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">

   <property name="transactionManager" ref="txManager"/>

   <property name="transactionAttributes">

     <props>

        <prop key="insert*">PROPAGATION_REQUIRED</prop>

        <prop key="update*">PROPAGATION_REQUIRED</prop>

        <prop key="delete*">PROPAGATION_REQUIRED</prop>

        <prop key="list">PROPAGATION_REQUIRED,readOnly</prop>

     </props>

    </property>

</bean>

<bean id="companyService" parent="baseTransactionProxy">

   <property name="target" ref="companyServiceTarget"/>

</bean>

<bean id="otherService" parent="baseTransactionProxy">

   <property name="target" ref="otherServiceTarget"/>

</bean>

(3)spring事物管理第三种配置方式:使用拦截器

<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">

    <property name="transactionManager" ref="txManager"/>

    <property name="transactionAttributes">

            <props>

                 <prop key="*">PROPAGATION_REQUIRED</prop>

            </props>

     </property>

</bean>

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">

    <property name="beanNames">

           <list>

                <value>companyServiceTarget</value>

           </list>

     </property>

    <property name="interceptorNames">

           <list>

                  <value>transactionInterceptor</value>

           </list>

    </proerty>

</bean>

这时可以直接使用companyServiceTarget。

(4)spring事物管理的第四种配置方式:使用tx命名空间
<tx:advice id="txAdvice"  transaction-manager="txManager">

      <tx:attributes>

           <tx:method name="insert*" propagation="REQUIRED"/>

            <tx:method name="update*" propagation="REQUIRED"/>

            <tx:method name="delete*" propagation="REQUIRED"/>

            <tx:method name="list" propagation="REQUIRED" read-only="true"/>

       </tx:attributes>

</tx:advice>

  <aop:config>

           <aop:pointcut id="interceptorPointCuts" expression="execution(* services.*Service(..))"/>

           <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts"/>

  </aop:config>

使用这种配置就需要把tx,aop的命名空间加入xml配置文件的开始。

<beans xmlns

               xmlns:xsi

               xmlns:p

               xmlns:context

               xmlns:aop

               xmlns:tx

               xsi:schemaLocation

                            

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值