• 【Spring】浅谈下 Spring IoC 和 DI 以及 Spring 实操


    一、Spring

    1. 为什么要使用Spring?

    • 解决代码耦合度高的问题

      以前的代码都是类似private IEmployeeDAO employeeDAO = new EmployeeDAOImpl();这样的代码,对象都是我们手动创建的,假如将实现类改成其它的,那就需要修改涉及到这个实现类的代码,这样大大增加了维护成本。(不符合开放-封闭原则)

    • 解决控制事务繁琐问题

      如果需要对某些业务方法进行事务管理,则需要写上开启事务、保存业务、提交事务、回滚事务等代码,假如有很多个业务方法都需要进行事务管理,则会造成大量重复代码,同时,维护上也很不方便。

    • 解决第三方框架运用太麻烦

      单纯使用MyBatis框架,则需要进行获取session对象、获取Mapper对象、执行相应SQL语句、提交事务、释放资源等,而对于使用者只关心使用的问题,而不在乎创建的问题。就比如我们需要使用手机打电话,我们关心的是直接使用手机,而不是自己造一部手机出来。

    2. Spring是什么?

    • Spring是一种轻量级的 IoC、DI 和 AOP 容器的开源框架。
    • 简单地说,Spring可以帮我们创建以及管理配置好的对象设置对象的属性值,并将对象(单例)存到Spring容器中,而我们需要用的时候,直接从Spring容器取出来就可以使用。

    3. Spring的优势

    Spring 除了不能帮我们写业务逻辑,其余的几乎什么都能帮助我们简化开发,作用如下

    • Spring 能帮我们低侵入/低耦合地根据配置文件创建及组装对象之间的依赖关系。
    • Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制等。
    • Spring 能非常简单的且强大的声明式事务管理。
    • Spring 提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,且自己也提供了一套 JDBC 模板来方便数据库访问。
    • Spring 提供与第三方 Web(如 Struts1/2、JSF)框架无缝集成,且自己也提供了一套 Spring MVC 框架,来方便 Web 层搭建。
    • Spring 能方便的与如 Java Mail、任务调度、缓存框架等技术整合,降低开发难度。

    4. Spring FrameWork体系

    5. Spring依赖

    1. <!-- spring上下文依赖 -->
    2. <dependency>
    3. <groupId>org.springframework</groupId>
    4. <artifactId>spring-context</artifactId>
    5. <version>5.0.8.RELEASE</version>
    6. </dependency>
    7. <!-- spring测试依赖 -->
    8. <dependency>
    9. <groupId>org.springframework</groupId>
    10. <artifactId>spring-test</artifactId>
    11. <version>5.0.8.RELEASE</version>
    12. <scope>test</scope>
    13. </dependency>

    二、IoC 和 DI

    1. IoC

    • Inversion of Control,控制反转
    • 将在程序中手动创建对象的控制权交给 IoC 容器,由 IoC 容器进行创建对象和管理对象

    2. DI

    • Dependency Injection,依赖注入
    • 创建对象过程中,将对象依赖属性(常量、对象)通过配置设置值给该对象

    IoC 和 DI都是一种思想或者称为想法,而Spring是这两种思想实现之一

    三、Spring 基础知识

    1. BeanFactory和ApplicationContext

    2. Spring 配置方式

    • XML-based configuration
    • Annotation-based configuration
    • Java-based configuration

    3. Spring IoC 管理 Bean 的原理

    • 通过Resource对象加载配置文件
    • 解析配置文件和Bean元素,将id作为bean的名字,class通过反射创建bean的实例
      bean类必须存在一个无参构造器
    • 调用getBean()方法时,从容器中返回对象实例

    4. XML基本配置

    1. <context:property-placeholder location="classpath:db.properties"/>
    2. <!--
    3. 若类名字以 FactoryBean 结尾,需要注意具体创建什么类型的对象存到容器中
    4. 初始化和销毁方法目前只有数据源对象才会配置
    5. -->
    6. <bean id="唯一性" class="类全限定名" [init-method="初始化方法名" destroy-method="销毁方法名"]>
    7. <property name="属性名" value="属性值"|ref="容器中另外一个 bean 的 id 值"/>
    8. ......
    9. </bean>
    10. ......

    5. 实现 FactoryBean 接口实例化

    Spring在对整个bean元素解析创建对象时,会先创建该工厂对象,但检测到这个类实现了FactoryBean接口,则会使用工厂对象调用getObject()方法创建bean对象,并把bean对象存入容器中。

    集成 MyBatis 框架使用,就会配置 org.mybatis.spring.SqlSessionFactoryBean

    6. Bean

    • bean的创建时机:启动 Spring 容器的时候创建所有的 bean

    • 作用域:singleton(默认)、prototype、request、session、application

    • 初始化和销毁:在配置文件中设置

      • 正常关闭容器,才会执行销毁方法

      • bean的scope为prototype时,容器只负责创建和初始化,不负责销毁。

        因为多例对象是一次性的,不需要进行保存,存放在spring容器外,如果存放在spring容器内,那么就会导致容器被这些对象占满

         

    四、第一个 Spring 程序

    1. 新建 Maven 项目并设置编译版本及添加依赖(pom.xml)

      1. <properties>
      2. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      3. <maven.compiler.source>16</maven.compiler.source>
      4. <maven.compiler.target>16</maven.compiler.target>
      5. </properties>
      6. <dependencies>
      7. <dependency>
      8. <groupId>com.alibaba</groupId>
      9. <artifactId>druid</artifactId>
      10. <version>1.1.9</version>
      11. </dependency>
      12. <dependency>
      13. <groupId>mysql</groupId>
      14. <artifactId>mysql-connector-java</artifactId>
      15. <version>5.1.45</version>
      16. <scope>runtime</scope>
      17. </dependency>
      18. <dependency>
      19. <groupId>org.projectlombok</groupId>
      20. <artifactId>lombok</artifactId>
      21. <version>1.18.20</version>
      22. <scope>provided</scope>
      23. </dependency>
      24. <dependency>
      25. <groupId>org.springframework</groupId>
      26. <artifactId>spring-context</artifactId>
      27. <version>5.0.8.RELEASE</version>
      28. </dependency>
      29. <dependency>
      30. <groupId>org.springframework</groupId>
      31. <artifactId>spring-test</artifactId>
      32. <version>5.0.8.RELEASE</version>
      33. <scope>test</scope>
      34. </dependency>
      35. <dependency>
      36. <groupId>junit</groupId>
      37. <artifactId>junit</artifactId>
      38. <version>4.12</version>
      39. <scope>test</scope>
      40. </dependency>
      41. </dependencies>
    2. 创建表

      1. CREATE TABLE `employee` (
      2. `id` bigint(20) NOT NULL AUTO_INCREMENT,
      3. `username` varchar(255) DEFAULT NULL,
      4. `password` varchar(255) DEFAULT NULL,
      5. `age` int(11) DEFAULT NULL,
      6. PRIMARY KEY (`id`)
      7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    3. 编写数据库四要素(db.properties)

      1. jdbc.driverClassName=com.mysql.jdbc.Driver
      2. jdbc.url=jdbc:mysql:///spring-demo
      3. jdbc.username=root
      4. jdbc.password=admin
    4. 编写 DAO 层代码

      1. public interface IEmployeeDAO {
      2. void save(String username, String password, age) throws Exception;
      3. }
      1. public class EmployeeDAOImpl implements IEmployeeDAO {
      2. private DataSource dataSource;
      3. public void setDataSource(DataSource dataSource) {
      4. this.dataSource = dataSource;
      5. }
      6. @Override
      7. public void save(String username, String password, age) throws Exception {
      8. @Cleanup
      9. Connection connection = dataSource.getConnection();
      10. @Cleanup
      11. PreparedStatement ps = connection.prepareStatement("INSERT INTO employee(username, password, age) VALUES(?, ?, ?)");
      12. ps.setString(1, username);
      13. ps.setString(2, password);
      14. ps.setInteger(3, age);
      15. ps.executeUpdate();
      16. }
      17. }
    5. 编写业务层代码

      1. public interface IEmployeeService {
      2. void save(String username, String password, Integer age) throws Exception;
      3. }
      1. public class EmployeeServiceImpl implements IEmployeeService {
      2. private IEmployeeDAO employeeDAO;
      3. public void setemployeeDAO(IEmployeeDAO employeeDAO) {
      4. this.employeeDAO = employeeDAO;
      5. }
      6. @Override
      7. public void save(String username, String password, age) throws Exception {
      8. employeeDAO.save(username, password, age);
      9. }
      10. }
    6. 编写 Spring 配置文件(applicationContext.xml)

      1. <?xml version="1.0" encoding="UTF-8"?>
      2. <beans xmlns="http://www.springframework.org/schema/beans"
      3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      4. xmlns:context="http://www.springframework.org/schema/context"
      5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
      6. <context:property-placeholder location="classpath:db.properties"/>
      7. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
      8. init-method="init" destroy-method="close">
      9. <property name="driverClassName" value="${jdbc.driver}"/>
      10. <property name="url" value="${jdbc.url}"/>
      11. <property name="username" value="${jdbc.username}"/>
      12. <property name="password" value="${jdbc.password}"/>
      13. </bean>
      14. <bean id="employeeDAO" class="cn.regex.ims.dao.impl.EmployeeDAOImpl">
      15. <property name="dataSource" ref="dataSource"/>
      16. </bean>
      17. <bean id="employeeService" class="cn.regex.ims.service.impl.EmployeeServiceImpl">
      18. <property name="employeeDAO" ref="employeeDAO"/>
      19. </bean>
      20. </beans>
    7. 编写测试类(EmployeeServiceTest.java)

      1. @RunWith(SpringJUnit4ClassRunner.class)
      2. @ContextConfiguration("classpath:applicationContext.xml")
      3. public class EmployeeServiceTest {
      4. @Autowired
      5. private IEmployeeService employeeService;
      6. @Test
      7. public void save() throws Exception {
      8. Employee employee = new Employee();
      9. employee.setUsername("regex");
      10. employee.setPassword("123456");
      11. employee.setAge(15);
      12. employeeService.save(employee);
      13. }
      14. }
  • 相关阅读:
    Mac电脑交互式原型设计 Axure RP 8汉化最新 for mac
    C++数据结构,三万字详解(强烈建议收藏)
    WebStorm的Vue工程如何用Bito插件进行单元测试
    linux私有化部署图片鉴黄docker版及nodejs版并通过java调用参考nsfwjs
    Android 9.0 SQLiteCantOpenDatabaseException SQLITE_CANTOPEN(不支持WAL模式)源码分析定位
    Openvpn服务端配置文件参数说明(server.conf)
    软件工程阶段测试4
    基于R语言机器学习方法与案例分析
    GitCode / 1024程序员开源挑战赛(10.23-11.14)
    G-Mixup: Graph Data Augmentation for Graph Classification
  • 原文地址:https://blog.csdn.net/LBWNB_Java/article/details/126718779