企业级框架Spring——学习总结之阶段1

本文介绍了Spring框架在企业级开发中的重要性,包括其简化开发、整合其他技术以及解决代码耦合问题。重点讲解了Spring的IoC/DI原理、AOP应用、如何通过控制反转实现依赖注入,以及构造方法、静态工厂、实例工厂和FactoryBean的不同实例化方式。
摘要由CSDN通过智能技术生成

        作者即将开启三期关于Spring开发的学习,为了深入理解spring的开发流程。

前言:

        1.为什么需要学习Spring的开发呢?有什么主要的作用?

  • 是Spring在市场的占有率与使用率高
  • Spring可以简化开发,降低企业级开发的复杂性,使开发变得更简单快捷
  • Spring可以框架整合,高效整合其他技术,提高企业级应用开发与运行效率,例如Mybatis框架的整合

        2.对于Spring的学习应该去学什么?

  •         Spring的IOC/DI
  •         Spring的AOP
  •         AOP的具体应用,事务管理
  •         IOC/DI的具体应用,整合Mybatis

        一:如何用Spring解决项目中耦合度高的问题

        业务层需要调用数据层的方法,就需要在业务层new数据层的对象,如果数据层的实现类发生变化,那么业务层的代码也需要跟着改变,发生变更后,都需要进行编译打包和重部署,所以,现在代码在编写的过程中存在的问题是:耦合度偏高

        如图所示我们应该如何去解决实现下方创建对象问题?————使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象,这种实现思就是Spring的一个核心概念

           二:IOC反转(控制反转)

        如上面的案例:使用对象时,由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转(IOC)。

         问题是Spring是如何实现控制反转的呢?————Spring提供了一个容器,称为IOC容器,用来充当思想中的"外部",负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象被创建或被管理的对象在IOC容器中统称为Bean,IOC容器中放的就是一个个的Bean对象

        上述案例中,当IOC容器中创建好service和dao对象后,程序能正确执行么?————不行,因为service运行需要依赖dao对象,IOC容器中虽然有service和dao对象,但是service对象和dao对象没有任何关系,需要把dao对象交给service,也就是说要绑定service和dao对象之间的关系

        如何建立关系呢?(在其他类中新建一个类,如何建立两者关系?)————DI依赖注入(在容器中建立bean与bean之间的依赖关系的整个过程)上述例子如图下建立依赖关系:

        

         三:案例详细介绍使用Spring的IOC过程

         1.首先增添spring的jar包(依赖包)pom.xml文件中

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.10.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
  </dependency>
</dependencies>

        2.添加案例中需要的类

        3.添加spring配置文件,在配置文件中完成bean的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!--bean标签标示配置bean
 id属性标示给bean起名字
 class属性表示给bean定义类型
-->
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
  <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"/>
</beans>

        注意事项:bean定义时id属性在同一个上下文中(配置文件)不能重复

        5.获取IOC容器

                使用Spring提供的接口完成IOC容器的创建,创建App类,编写main方法

public class App {
  public static void main(String[] args) {
    //获取IOC容器
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
 }
}

        6.从容器中获取对象进行方法调用

public class App {
  public static void main(String[] args) {
    //获取IOC容器
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
//    BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//    bookDao.save();
    BookService bookService = (BookService) ctx.getBean("bookService");
    bookService.save();
 }
}

总结:不在使用new创建类的对象,直接从Spring管理的IOC容器中获取对象

        四:IOC的引入简化代码耦合

        在 BookServiceImpl 的类中依然存在 BookDaoImpl 对象的new操作,它们之间的耦合度还是比较高,这块该如何解决,就需要用到下面的 DI:依赖注入

        1: 去除代码中的new,在BookServiceImpl类中,删除业务层中使用new的方式创建的dao对象

public class BookServiceImpl implements BookService {
  //删除业务层中使用new的方式创建的dao对象
  private BookDao bookDao;
  public void save() {
    System.out.println("book service save ...");
    bookDao.save();
 }
}

        2:为属性提供setter方法,在BookServiceImpl类中,为BookDao提供setter方法

public class BookServiceImpl implements BookService {
  //删除业务层中使用new的方式创建的dao对象
  private BookDao bookDao;
  public void save() {
    System.out.println("book service save ...");
    bookDao.save();
 }
  //提供对应的set方法
  public void setBookDao(BookDao bookDao) {
    this.bookDao = bookDao;
 }
}

3:修改配置完成注入,在配置文件中添加依赖注入的配置(建立关系)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!--bean标签标示配置bean
 id属性标示给bean起名字
 class属性表示给bean定义类型
-->
  <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
  <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <!--配置server与dao的关系-->
    <!--property标签表示配置当前bean的属性
   name属性表示配置哪一个具体的属性
   ref属性表示参照哪一个bean
-->
    <property name="bookDao" ref="bookDao"/>
  </bean>
</beans>

        注意:配置中<property name="bookDao" ref="bookDao"/>的两个bookDao的含义是不一样的
        1.name="bookDao"中 bookDao 的作用是让Spring的IOC容器在获取到名称后,将首字母大写,前面加set找对应的 setBookDao() 方法进行对象注入

        2.ref="bookDao"中 bookDao 的作用是让Spring能在IOC容器中找到id为 bookDao 的Bean对象给bookService 进行注入(如下关系图)

        总结:在案例中我们通过set方法再次通过修改xml文件,建立两个Bean之间的关系就是建立了依赖注入,这样我们就可以在其他类中直接创建类对象,在IOC容器中找到这个对象并且使用,而不用去new,极大的降低了代码的耦合性

        五:如何配置Bean(建立关系)

        前面我们通过DI依赖注入,配置了简单的Bean让两个bean建立了关系方便开发,减低耦合

Bean中的属性介绍:

        id属性:就是bean的id,IOC容器可以通过唯一的id来找到这个Bean

        class属性:Bean的类型,就是配置Bean的全路径类名

        name属性:bean的别名配置,<别名可以有多个,使用逗号,分号,空格进行分隔

                   根据名称容器中获取bean对象,例如:name="service service4 bookEbi":

//此处根据bean标签的id属性和name属性的任意一个值来获取bean对象
    BookService bookService = (BookService) ctx.getBean("service4");

        ref属性:bean依赖注入的ref属性指定bean,必须在容器中存在

        scope属性:来实现bean的非单例创建(singleton 默认为单例 prototype 为非单例)

        

        六:Bean的实例化方法:

              我们已经知道了对象可以由Spring管理的IOC容器创建了,但是我们如何去创建对象呢?

              实例化bean的三种方式—— 构造方法 , 静态工厂 和 实例工厂

         1.构造方法实例化Bean:

               1.创建接口和类:

public interface BookDao {
  public void save();
}
public class BookDaoImpl implements BookDao {
  public void save() {
    System.out.println("book dao save ...");
 }
}

                2.配置Spring容器:

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

                3.编写运行程序:

public class AppForInstanceBook {
  public static void main(String[] args) {
    ApplicationContext ctx = new
      ClassPathXmlApplicationContext("applicationContext.xml");
    BookDao bookDao = (BookDao) ctx.getBean("bookDao");
    bookDao.save();
 }
}

                4.类中提供构造函数测试:

public class BookDaoImpl implements BookDao {
  public BookDaoImpl() {
    System.out.println("book dao constructor is running ....");
 }
  public void save() {
    System.out.println("book dao save ...");
 }
}

                5:将构造函数改成private测试:

public class BookDaoImpl implements BookDao {
  private BookDaoImpl() {
    System.out.println("book dao constructor is running ....");
 }
  public void save() {
    System.out.println("book dao save ...");
 }
}

总结:能执行成功,说明内部走的依然是构造函数,能访问到类中的私有构造方法,显而易见
Spring底层用的是反射
        

        2.静态工厂实例化

(1)在spring的配置文件application.properties中添加以下内容:

  • class:工厂类的类全名
  • factory-mehod:具体工厂类中创建对象的方法名
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-
method="getOrderDao"/>

(2)在AppForInstanceOrder运行类,使用从IOC容器中获取bean的方法进行运行测试

ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
    OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
    orderDao.save();

        看到这,可能有人会问了,你这种方式在工厂类中不也是直接new对象的,和我自己直接new没什么太大的区别,而且静态工厂的方式反而更复杂,这种方式的意义是什么?————了解为主

 3.实例工厂实例化

(1)在spring的配置文件中添加以下内容:

        <bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
        <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>     

  

 (1)创建一个工厂类OrderDaoFactory并提供一个普通方法,注意此处和静态工厂的工厂类不一样的地方是方法不是静态方法

public class UserDaoFactory {
  public UserDao getUserDao(){
    return new UserDaoImpl();
 }
}

        (2)编写AppForInstanceUser运行类,在类中通过工厂获取对象

public class AppForInstanceUser {
  public static void main(String[] args) {
    //创建实例工厂对象
    UserDaoFactory userDaoFactory = new UserDaoFactory();
    //通过实例工厂对象创建对象
    UserDao userDao = userDaoFactory.getUserDao();
    userDao.save();
}
  • factory-bean:工厂的实例对象
  • factory-method:工厂对象中的具体创建对象的方法名,对应关系如下:
  • factory-mehod:具体工厂类中创建对象的方法名

总结:配置的过程还是比较复杂,所以Spring为了简化这种配置方式就提供了一种叫 FactoryBean 的方式来简化开发

简化开发的方式:

        FactoryBean的使用

(1)创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法

        

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
  //代替原始实例工厂中创建对象的方法
  public UserDao getObject() throws Exception {
    return new UserDaoImpl();
 }
  //返回所创建类的Class对象
  public Class<?> getObjectType() {
    return UserDao.class;
 }
}

(2)在Spring的配置文件中进行配置

<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/> 

(3)AppForInstanceUser运行类不用做任何修改,直接运行

总结:Spring的IOC实例化对象的三种方式分别是:

  • 构造方法(常用)
  • 静态工厂(了解)
  • 实例工厂(了解)
  • FactoryBean(实用)

这些方式中,重点掌握 构造方法 FactoryBean 即可。
需要注意的一点是,构造方法在类中默认会提供,但是如果重写了构造方法,默认的就会消失,在使用的过程中需要注意,如果需要重写构造方法,最好把默认的构造方法也重写下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值