Spring框架的ioc和aop介绍

----------------------------------------------------------------------------------------------------------------------------------------------------------------        

我们在学习的时候,首先想到的肯定是查阅各种资料来系统学习一下,但是最后我么往往会发现,不管是哪的资料依然是看不懂(o(╯□╰)o)---------------------所以本文章只介绍Spring的最基本的原理,至于后续的知识,之后再介绍,刚刚接触Spring的同学不妨看一看本篇总结,也许会对你很有帮助~~大佬们如果看到错误的话,请开始你们的批评与指正~~(*^▽^*)。学习就是这么一个过程,不断地总结,发现错误,总结

------------------------------------------------------------------------------------------------------------------------------------------------------------------

       首先,我们来一句网上或者书上都有的关于Spring的一句官话。这也是刚刚学习Spring的初学者最先看到的一句话:

       Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架

       呃。。。。。看不懂。。。。因为每个名词所包含的内涵和逻辑都是可以写好几篇文章的,接下来我就给大家整理一下

       一、轻量级,轻量级是比较好理解的(这里直接搬来百度上的解释了):从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。此外,Spring是非侵入式的:典型地,Spring应用中的对象不依赖于Spring的特定类。

      二、控制反转(ioc):

             控制反转这个词晦涩难懂,不过重要的是,我们需要理解为什么是反转?

           (有没有更晕了?别着急,我们慢慢来)。

            在这里我举一个不太成熟的小例子:

             比如说孙毅弟弟大学毕业之后北漂到北京工作,他需要找一个房子来住,下边是示意图。而这时候,房子就是我们需要调用的类(为了更好的和下边对应这里写作user类),而孙毅弟弟就是调用房子类的servlet类,下边是示意图:

                                                         

          而使用了ioc之后就是相当于,在孙毅弟弟和房源之间增加了一个房屋中介,这个房屋中介就是我们的ioc容器(这里注意,ioc是一个概念,而ioc容器是一种技术实现):

                                                

      实现ioc的其中的一个很重要的技术是依赖注入(DI),孙毅弟弟依赖房源,房屋中介将自己管理着的房源注入孙毅弟弟。

 

为了更好地理解控制反转的思想,首先我们先来看一下平时我们在进行类的调用时我们是怎么做的。这里用用户(user类)来举例:

//用户类
public Class UserService{
   //方法add:增加一个用户
    public void add(){
      //增加一个用户操作*****
   }
}


/*现在我们要在Servlet类中调用User接口来增加一个用户了*/

UserService user=new UserService();

user.add();

(我们的调用的场景可以想象成项目构建时我们的controll层调用前一层Service时的接口的场景,或者其它层)看起来这样的调用方式万事大吉了,实际上没有学框架前刚刚接触JavaEE时也是这样做的。

   但是我们来思考一下:我们调用User类的add()方法不只是调用一次,我们可能在十个甚至是上百个Servlet中来声明User类来调用add()方法,假如万一我不调用User类了,而是调用他的子类来满足不同的需求了,是不是那些调用User类的Servlet都要报错了呢?我们是不是还得去改那成百个调用,这就暴露出来一个问题,这代码的耦合度 太高了

  后来那些前辈专家们,为了解决这个耦合的问题,就创造出来一种解决方法:工厂模式。

  工厂模式:我建立一个工厂类,在工厂类中调用User类中的add方法来增加一个用户,当我User类改变的时候,我就只要改变一下工厂类中的调用就可以了。以下是上面代码解耦合之后的代码:

//被调用的Service类
public Class userService{
  pubilc void add(){}
}

//创建一个工厂类Factory类,直接返回的是userService类
public Class Factory{
  public static userService getuserService(){
  return new userService();
}
//Servlet中调用
public Class userServlet{
  userServive s=Factory.getuserService;
}
}

有没有发现,如果我的userService类要改变,我就只要改变一下工厂类就可以了?为了更深入的理解工厂模式,我们再来看一个例子:

//创建一个接口:
public interface Shape {
   void draw();
}
//使用接口实现各种类
   //1.
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}   
  //2.
public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}
 //3.
  public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}


//现在创建工厂类:
public class ShapeFactory {
    
   //使用 getShape 方法获取形状类型的对象
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}

//使用工厂:
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
 
      //获取 Circle 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取 Rectangle 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
 
      //获取 Square 的对象,并调用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
   }
}

/**********--------得到结果----------*********/
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.



   到这里,相信我们对工厂模式都有一个比较深刻的了解了,但是工厂模式和我们的Spring框架有什么关系呢?其实我们的ioc的依赖注入和工场模式的思想非常的相似,可以理解为我们的ioc的控制反转就是用工厂模式的思想来实现的,换句话说工厂模式就是实现ioc的技术之一,只不过不仅仅是工厂模式就是了,不过我们只需要配置就好了。

 

重点来了:现在正式来介绍我们的ioc,我们的ioc用到的技术(1)xml配置文件(2)dom4j解析xml(3)工厂模式(4)反射机制

 

   1.创建xml配置文件

<bean id="userService"    class="cn.itcast.userService">

  2.

(2)创建一个工厂类:(使用的是dom4j解析配置文件+反射机制)

     public class Factory{
      public static UserService getService(){
       1.使用dom4j解析xml文件中的bean类
          根据id值userService,得到id 对应的class属性值 赋给一个字符串
          String className="class属性值"   ————注意这里和bean中的路径是对应的
          
       2.//使用反射机制创建对象

          class clazz = class.forName("className");
           //创建类的对象
          UserService service = clazz.newInstance();    //这个方式得到的就是反射中的对象
          return service;

}

}

     当我们再想使用这个类的时候,就使用这个工厂类~

     到这里大家是不是明白了Spring框架的ioc了呢?总的来说,Spring的很重要的一个功能就是降低类之间的耦合度,而Spring实现所需要的技术有:(1)xml配置文件(2)dom4j解析xml文件(3)工厂模式 (4)反射

 

 

二、下边我们来介绍一下Spring的aop的原理:

          官方介绍:aop的意思即是面向切面的编程。

           面向切面编程指的就是如果我要在我原有的代码中拓展功能,我只需要修改配置即可,而不需要修改源代码。

          和往常一样,我们先来用一个浅显易懂的例子来介绍我们的aop的原理。

         孙毅弟弟作为一个新入职的小码农 现在新建一个用户的类,这个类中有一个方法add(),而这个方法的功能是,向我们的数据库中添加一条数据,即一个用户:

public Class User{
   //添加用户
    public void add(){
    /*添加进数据库的操作*/
 }
}

         现在,领导要我添加一个功能,这个功能是在每次我向数据库中添加数据时,在拓展一个添加日志的功能,于是孙毅弟弟就打开了我们的源代码(上边的User类)开始改

public Class User{
   //添加用户
    public void add(){
    /*添加进数据库的操作*/
    /*添加日志的操作*/
 }
}

但是每次领导让孙毅弟弟添加新功能时,孙毅弟弟都要从项目的一大堆类,一大堆代码中去找到相应的类,然后再到对应的地方修改源码,,,孙毅弟弟觉得太麻烦了,于是他想出了一个之前学过的办法:纵向抽取

  纵向抽取:就是继承

 

 

 

 

 

   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章