Spring FrameWork 读书笔记

来源:互联网 发布:金华淘宝大学 编辑:程序博客网 时间:2024/06/11 23:50

《Spring 开发指南》 台湾知名专家夏昕编写,以前在图书馆偶尔翻阅过,今天得到这本电子书,感觉还是蛮不错的,虽然讲的比较浅,没有深入浅出Hibernate讲的那么深,但在工作中使用还是绰绰有余的。

一   控制反转IOC(Inversion of Control) 也叫依赖注入(Dependence Injection)是由容器控制控制程序之间的关系而非由代码直接控制

二   注入方法:

      (1)、接口注入

                 doGet(HttpServletRequest request,HttpServletResponse response){}

              其中HttpServletRequest和HttpServletResponses实例是由Servlet Container容器在运行时动态注入,(依赖关系是在运行时建立的,将调用者和实现者在编译时分离).

     (2)、设置注入

                通过Setter 和getter方法来注入(常用)

     (3)、构造子注入

                 public class DIConstructor{

                          private final DataSource dataSource;

                         private final Stirng message;

                         public DIConstructor(DataSource dataSource,String message){

                                           this.dataSource=dataSource;

                                           this.message=message;

                        }  

                 }

                依赖关系是通过类的构造函数建立,容器通过调用类的构造函数方法,将其需要的依赖关系注入其中。

 

四  面向方面AOP(Aspect oriented programmer)

         与OOP的区别:OOP可以对雇员进行封装成一个类,并将相应的属性和行为封装其中,是对实体进行封装,而AOP是对业务处理这一切面进行提取。即:OOP面向名字领域,AOP面向动词领域。如”权限检查“这一动作片断。

 

 

  1)、连接点(JoinPoint) 程序运行到某个阶段点,如:某个方法调用,抛出异常

  2)、处理逻辑(Advice) 连接点采用的处理逻辑

           Around  在连接点前后插入预处理的过程和后处理的过程

           Before   仅仅在连接点之前插入预处理过程

           Throw    连接点抛出异常时进行异常处理

3)、切点(PintCut)一系列连接点的集合,它指明处理方式(Advice)将在何时触发,比如事务管理中ops中的prop<prop key="save*"></prop>表明在插入是触发。

 

五、Spring 基本概念
(1) Spring 是轻量级且非侵入性,说它是轻量级的是因为它不依赖容器。说它非侵入性是因为应用独立。不依赖于任何容器。
    和EJB的区别:EJB称之为重量级是因为必须要依赖依赖EJB容器。侵入性高,当要把应用单独拿出来时,不容易,因为应用必须依赖容器,离开容器编译都通不过。虽然EJB 也提供事务管理,但必须是EJB组件才可以,而Spring提供声明是事务,只要是普通的对象pojo就可以声明是事务。
(2) 装配依赖关系IOC(Inversion Of Control)控制反转思想。依赖关系不是客户去做,比如创建对象,建立关系。而是交给IOC容器去管理(主动权给了IOC容器)。在配置文件中把所有关系都配好。当一个组件依赖另一个组件时。并且这种关系已经在IOC容器中配置好了,当A需要B时自动会拿到B,自动会把B new好给A,但是A必须提供构造函数,或者必须实行set(A a)方法,把new 好的对象给A。这个就称之为依赖注入DJ(Dependency Injection);DJ是实现依赖关系的一种方法,还有一种叫依赖查找。
ej
public class A{
   public save(new B());这个是普通的A依赖B关系,A要使用B。就要请求一对象
}

public class A{
  public B b;
  (1) 构造方法注入法
  public A(B b){
   this.b = b;
  }
  (2) set方法注入法
  public void setB(B b){
    this.b = b;
  }//通过setB();方法,B主动把自己的对象给A,也就是B是主动,A是被动。这就是DJ思想。
}
(3) AOP 比如Filter思想,对方法在执行前做什么,执行后做什么,抛异常做什么

(4) 与其它框架的集成。比如:Struts Hibernate。提供Session和事务管理。而使客户只关心业务就可以了。其它事情都不用担心。

 

六:applicationContext.xml文件的编写
<beans>
<!-- 普通bean --->
<bean id="bean1" class=""/>
<bean id="bean2" class=""/>
<!-- 引用bean -->
<bean id="bean3" class="" ref="bean1">
或者 bean3 依赖两个bean3和bean4
<bean id="bean3" class="">
 <property name="bean3Impl" ref="bean3"/>
 <property name="bean4Impl" ref="bean4"/>
</bean>
<!-- 公共属性的bean-->
<bean id="bean4" class="" abstract="true">
 <property name="name" value="chen"/>
 <property name="password" value="123"/>
</bean>
<bean id="bean5" class="" parent="bean4">
 <property name="age" value="98"/>
</bean>

<!-- array,list,set-->
<bean id="bean6" class="">
  <list>
   <value>123</value>
   <value>345</value>
  </list>
</bean>

<!-- map -->
<bean id="bean7" class="">
 <map>
  <entry key="key1" value="value1"/>
  <entry key="key2" value="value2"/>
 </map>
</bean>
</beans>

 

BeanFactory 加载applicationContext.xml并且从IOC容器得到bean

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

 

BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
  UserManagerImpl userManager = (UserManagerImpl)factory.getBean("userManager");

  userManager.save();

 

七:spring 的作用域
在默认情况下,如果多次调用bean,他们是相等的。它的作用域是singleton,如果把它设置为prototype,每次调用getBean()会产生不同的对象,它们是不等的。
<bean id="" class="" abstract="true" scope="prototype"

 

八:spring 的装配方式
(1) byName
   如果一个bean 引用了多个bean配置文件如下
   如:bean1引用了bean2 bean3 bean4
  <bean id="bean1" class="">
   <property name="bean2" ref="bean1"/>
  <property name="bean3" ref="bean2"/>
   <property name="bean4" ref="bean3"/>
  </bean>
  如果通过byName(在配置文件beans头部加上<beans default-autowire="byName") 去自动装配,则可以大大简化配置文件
 <bean id="bean1" class=""/>这样,在Bean1中包含bean2  bean3 bean4 属性并且有setBean2() setBean3() setBean4()方法,spring会自动查找名字为bean2  bean3 bean4
  的bean的定义,并且自动装配上。
(2) byType
  就是bean在引用多个bean的时候自动根据类型去查找,而忽视了名字。(在配置文件beans头部加上<beans default-autowire="byType")
 如 bean1 有三个属性
  private Bean2 bean2  属于cn.com.chenlly.Bean2
  private Bean3 bean3  属于cn.com.chenlly.Bean3
  private Bean4 bean4  属于cn.com.chenlly.Bean4

而在配置文件中,因为class=""已经指定了所属类。所以自动会根据class类型去装配,而忽视了名字,所以id="bean2" 或者id="bean22" 都无关紧要。ioc容器都会把他们查找到的。
 <bean id="bean2"   class="cn.com.chenlly.Bean2"/>
 <bean id="bean3"   class="cn.com.chenlly.Bean3"/>
 <bean id="bean4"   class="cn.com.chenlly.Bean4"/>

 

九:AOP 静态代理和动态代理
 声明式服务能力
 proxy 可以控制原对象,但不能修改原对象。代理类必须和原来的接口(目标类)是一样的不能改变的
 典型的横切逻辑应用:比如在调用原对象之前进行安全性检查。
 代理模式有两种:静态代理和动态代理。动态代理即AOP思想。下面给出静态代理的例子
UserManager 接口:
public interface UserManager{
 public void addUser(String name,String passwrod);
 public void deleteUser(int id);
 public void modifyUsr(int id);
}
UserManagerImpl 类(目标类)
public class UserManagerImpl implements UserManager{
 public void addUser(String name,String passwrod){
  //todo something
 }
 public void deleteUser(int id){
  //todo something
 }
 public void modifyUsr(int id){
  //todo something
 }
}

UserManagerProxyImpl 代理类
public class UserManagerProxyImpl implements UserManager{
 private UserManagerImpl userManagerImpl;
 public UserManagerProxyImpl(UserManagerImpl userManagerImpl){
  this.userManagerImpl=userManagerImpl;
 }
 //必须和目标类有一样的实现
 public void addUser(String name,String passwrod){
  (1)安全性检查
  this.checkSecurity();
                (2)增加姓名
  this.userManagerImpl.addUser(name,password);
 }
 public void deleteUser(int id){
  (1)安全性检查
  this.checkSecurity();
                (2)删除用户
  this.userManagerImpl.deleteUser(id);
 }
 public void modifyUsr(int id){
  (1)安全性检查
  this.checkSecurity();
                (2)修改用户
  this.userManagerImpl.modifyUser(id);
 }
 //安全性检查
 private void checkSecurity(){
  //todo something
 }
}
这样只要客户端做增加,删除,修改都会增加一个安全性检查的功能。但是静态代理有个缺点就是检验安全性方法遍布整个代理类当中。所以引入了动态代理的思想
把连接点放在一个类里(模块化),当在运行期的时候,把这个方法自动切入。

下面给出动态代理的例子
把要进行安全性检查的方一个法模块化,写在类里。当我们生产了代理对象的时候,如果调用代理方法的时候,
会自动默认调用invoke方法。这个模块化的类就是所谓的切面(Aspect),安全性检查就是advice,
import java.lang.reflect.InvocationHandler;//是代理实例的调用处理程序 实现的接口。
import java.lang.reflect.Proxy;//
public class SecurityHandler implements InvocationHandler{
 private Object targetObject;//目标实例
 public Object newProxy(Object targetObject){
  this.targetObject = targetObject;
  //返回一个目标对象的代理类
  return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//目标程序的类加载器
                                targetObject.getClass().interfaces(),//目标程序的接口
           this);//代理指定调用的处理程序
 }

 public Object invoke(Object proxy,Method method,Object args) throws Throws{
  //安全性检查,这是一个before Advice
  checkSecurity();
  //调用目标对象的正是实现,有可能有返回值,
               Object res = null;
        try{
   res = method.invoke(targetObject,args);
        }catch(Exception ex){
  ex.printStackTrace();
        }
 }


 //安全性检查
 private void checkSecurity(){
  //todo something;
 }
}

//客户端调用
public class Client{
  SecurityHandler sh = new SecurityHandler();
 //得到代理类,Annotation就是使用了动态代理机制
 UserManagerImpl userManagerImpl = (UserManagerImpl)sh.newProxy(new UserManagerImpl());
        userManagerImpl.addUser();
 userManagerImpl.deleteUser(12);
}

 

 

十:Spring和Hibernate 的事务集成
Spring 配置文件
<!-- 配置SessionFactory-->
<bean id="sessionFactory" class="org.springframwork.orm.hibernate3.LocalSessionFactoryBean">
 <property name="configLocal">
  <value> classpath:/hibernate.cfg.xml</value>
 </property>
</bean>

<!--配置事务管理器-->
<bean id="sessionManager" class="org.spring.orm.hibernate3.HibernateTransactionManager"
 <property name="sessionFactory" ref="sessionFactory">
</bean>

<!--配置事务的传播性-->
 <bean id="baseTxService"
  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
  abstract="true">
  <property name="transactionManager" ref="transactionManager" />
  <property name="proxyTargetClass" value="true" />
  
  <property name="transactionAttributes">
   <props>
    <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop><!-- 只读事务-->
    <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="show*">PROPAGATION_REQUIRED,readOnly</prop>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="remove*">PROPAGATION_REQUIRED</prop>
    <prop key="delete*">PROPAGATION_REQUIRED</prop>
    <prop key="execute">PROPAGATION_REQUIRED</prop>
   </props>
  </property>
 </bean>

 在service 层加事务

 <bean id="contractManagerimpl" parent="baseTxService">
  <property name="target">
   <bean class="com.ngtc.contract.service.impl.ContractManagerImpl" autowire="byName"></bean>
  </property>
 </bean>

十一、spring 和 Struts 的集成。
 Struts 的Action 通过请求path来找type定义的Action,如果没有就创建,如果有从map里取。
 通过Spring集成的Struts Action是通过ActionProxy来拿到BeanFactory 和从IOC容器中取的
 type里对于的Action,不过在配置Action的配置文件是,name="/xxx" 必须和struts里的path
 必须一样。如
 struts配置文件
 <action path="/login"
         type="org.springframework.web.struts.DelegationActionProxy"//是一个代理Action 主要是取的BeanFactory,然后根据<action>中的path属性值到IOC容器中去得到本次请求对应的Action
         name="loginForm"
         scope="request
         >
         <forward name="success" path="/success.jsp">
  </acton>
 spring 配置文件
 <bean name="/login" class="cn.com.chenlly.LoginAction">
  <property name="" ref="">//注入业务逻辑对象
 </bean>

原创粉丝点击