spring学习初步

一 开始spring之路

   1 spring 版的hello world

 

      (1) 首先创建一个Greeting Service 接口, 将实现从接口中分离出来。

 

       package cn.bupt.duming.service;

public interface GreetingService {

         void sayHello() ;
   
}

 

    (2) GreetingServiceImpl 是GreetingService接口的实现

 

          尽管看起来,在此处没必要隐藏接口,但是我们还是建议将实现与接口分离。

  public class GreetingServiceImpl implements GreetingService {

    private String greeting ;

    public GreetingServiceImpl(){       
    }
   
    public GreetingServiceImpl(String greeting){       
        this.greeting = greeting ;
    }
    public void sayHello() {       
        System.out.println(greeting);           
    }

    public void setGreeting(String greeting){
       
        this.greeting = greeting ;
    }
   
}

 

 现在的问题是在何处调用上述的set方法,和构造函数。

 

(3) 在Spring 中配置 HelloWorld.xml

 

  <bean id = "greetingService" class = "cn.bupt.duming.service.GreetingServiceImpl" >
    <property name="greeting" value = "hello world"></property>
  </bean>

 

   在文件中配置了一个 GreetingServiceImpl的实例 ,   <property>是设置属性的值,  就是  GreetingServiceImpl

  实例中的greeting 的值。

 

 

(4) 在Spring 中配置实例的构造函数

 

  <bean id = "greetingService" class = "cn.bupt.duming.service.GreetingServiceImpl" >
    <constructor-arg value = "hello world"></constructor-arg>
  </bean>

 

 

(5)测试类

 

      BeanFactory factory = new XmlBeanFactory(
                 new FileSystemResource("applicationContext.xml")) ;
        GreetingService greetingService = (GreetingService) factory.getBean("greetingService") ;
        greetingService.sayHello() ;

 

这里的BeanFactory就是Spring 容器。

 

二 依赖注入 DI

 

    1 DI应用

       (1) 骑士接口

 

            public interface Knight {
 
               Object embarkOnQuest() ;
   
           }

 

 

 

       (2) 圆桌武士Bean

                public class KnightOfTheRoundTable implements Knight{

    private String name ;
   
    private Quest quest ; //只定义接口实例,这样不光能进行圣杯探险,还能进行其他的探险
   
    public KnightOfTheRoundTable(String name){
         
        this.name = name ;
        quest = new HollyGrailQuest() ;
    }

    public Object embarkOnQuest() {
        // TODO Auto-generated method stub
        return quest.embark() ;
    }
   
   
    // 这样骑士可以进行各种各样的探险,不一定是圣杯探险
    public void setQuest(Quest quest){
       
        this.quest = quest ;
    }

 

(3) 探险接口

 

     public interface Quest {

    abstract Object embark() ;
}

 

(4) 进行圣杯探险

 

 

   public class HollyGrailQuest implements Quest{
  
    public HollyGrailQuest(){
      
   }
    public Object embark() {
        // TODO Auto-generated method stub
       
        System.out.println("探险开始");
        return new Object();
    } 
}

 

 

 以上代码实现与接口相分离,减少了耦合。

 

(5) 配置文件


         在此处配置具体的探险类

      <bean id ="quest" class="cn.bupt.duming.di.HollyGrailQuest">
      </bean>

 

       // 在此处构造骑士 , 并和相应的探险任务建立关联

  
   <bean id="knight" class = "cn.bupt.duming.di.KnightOfTheRoundTable"> 
           <constructor-arg value="duming"></constructor-arg> 
           <property name="quest" ref="quest" ></property>
   </bean>

 

(6) 理解DI

 

      Di 只是一种松散耦合的代码,这样尽可以是应用对象之间保持疏远的关系。

 

三   应用AOP

        1 AOP介绍

           AOP用来在软件系统中实现业务分离,使用AOP,你可以使各种功能层来覆盖核心业务层。它将安全、事务、

和日志功能与核心业务层相分开。

 

       2 具体应用

        我们在上面的骑士的例子中,添加一个日志切面。

 

   (1) 需求

          为每一个骑士增加一个诗人相陪伴,用歌曲来记录骑士的功绩和行动。

 

   (2)代码实现

 

         Minstrel实现类

     public class Minstrel {

    public void singBefore(Knight knight){        
        System.out.println("sing before");   
    }
       
    public void singAfter(Knight knight){       
        System.out.println("singafter");       
    }             
}

 

      //在圆桌骑士类中增添诗人的属性

 

public class KnightOfTheRoundTable implements Knight{

    private String name ;
   
    private Quest quest ;
   
    private Minstrel minstrel ;
   
   
   
   
    public void setMinstrel(Minstrel minstrel) {
        this.minstrel = minstrel;
    }


    public KnightOfTheRoundTable(String name){
         
        this.name = name ;
        quest = new HollyGrailQuest() ;
    }

    public Object embarkOnQuest() {
        // TODO Auto-generated method stub
       
        minstrel.singBefore(this) ;
       
        minstrel.singAfter(this) ;
       
        return quest.embark() ;

    }
   
   
    public String getName() {
        return name;
    }

    // 这样骑士可以进行各种各样的探险,不一定是圣杯探险
    public void setQuest(Quest quest){
       
        this.quest = quest ;
    }

 

 

配置文件新增部分如下:

 

    <bean id ="minstrel" class = "cn.bupt.duming.di.Minstrel">
  
   </bean>
  
   <bean id="knight" class = "cn.bupt.duming.di.KnightOfTheRoundTable">
       
        <constructor-arg value="duming"></constructor-arg>
       
           <property name="quest" ref="quest"></property>
           <property name="minstrel" ref="minstrel"></property>
   </bean>

 

 

 

 

(3) 缺陷

 

     代码中红色部分显示,每个骑士在继续探险前,必须吩咐诗人谱一首曲子,在探险之后,骑士必须告诉诗人让其歌颂他

得事迹。   理想状态下,骑士应该不用关心诗人,简单的说诗人提供的服务超过了骑士的责任,也就是说诗人的工作和骑士

的工作交织在一起 。所以应该把诗人实现为切面,并把他写歌的服务提供给骑士。

 

 

(4)编织切面

          配置文件如下:

<aop:config>
     
    <aop:aspect ref="minstrel">
       <aop:pointcut   id="questPointcut"
       expression ="execution(* *.embarkOnQuest(..))
         and target(bean)"/>
      
       <aop:before
          method="singBefore"
          pointcut-ref="questPointcut"
          arg-names="beans"
         />
        
       <aop:after-returning
          method="singAfter"
          pointcut-ref="questPointcut"
          arg-names="bean" 
         />   
    </aop:aspect>
   </aop:config>

 

  骑士类无需知道诗人的存在,作为一个切面,诗人自动处理歌颂事项。结果骑士恢复到了一个更简单的形式。

 

 public class KnightOfTheRoundTable implements Knight{

    private String name ;
   
    private Quest quest ;

    public KnightOfTheRoundTable(String name){
         
        this.name = name ;
        quest = new HollyGrailQuest() ;
    }
    public Object embarkOnQuest() {
        // TODO Auto-generated method stub   
        return quest.embark() ;
    }

    public String getName() {
        return name;
    }
    // 这样骑士可以进行各种各样的探险,不一定是圣杯探险
    public void setQuest(Quest quest){
       
        this.quest = quest ;
    }
   
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值